Java批量操作和遍历文件程序收集 1.计算文件夹内文件数量 2. 拷贝并合并指定文件到指定文件夹下 3. 遍历所有子文件夹找出重名文件 4.将所有的文件名格式化后输出 (未完待续)
public class Main {
public static void main(String[] args) {
System.out.println(getCount("C:\Users\zhangzeyu\Desktop\人脸识别整理"));
}
public static int getCount(String path) {
return getCount(new File(path));
}
/**
* 递归获取文件夹内的文件数量
*/
public static int getCount(File root) {
if (root.isFile()) {
return 1;
} else if (root.isDirectory()) {
File[] files = root.listFiles();
if (files == null) {
return 0;
}
int sum = 0;
for (File file : files) {
sum += getCount(file);
}
System.out.println(root.getName() + ":" + sum);
return sum;
} else {
throw new RuntimeException("error");
}
}
}
核心的 API 有
- File#isFile() 检验一个文件是否是一个普通文件
- File#isDirectory() 检查一个文件是否是一个文件夹
- File#listFiles() 返回一个抽象路径名数组,该数组表示此抽象路径名表示的目录中的文件。
2. 拷贝并合并指定文件到指定文件夹下
拷贝 C:UserskendoziyuDesktop人脸识别整理 文件夹及其子文件夹下的文件到 C:UserskendoziyuDesktop人脸识别整理focus_faceface 文件夹下。
设置仅拷贝后缀为 .jpg 的文件
import java.io.File;
import java.io.FileFilter;
import java.io.IOException;
import java.nio.file.Files;
import java.util.Scanner;
public class Main {
public static void main(String[] args) throws IOException {
copyAndMergeFile("C:\Users\kendoziyu\Desktop\人脸识别整理",
"C:\Users\kendoziyu\Desktop\人脸识别整理\focus_face\face",
file -> file.getName().endsWith(".jpg") || file.getName().endsWith(".JPG"));
}
public static void copyAndMergeFile(String formDirectory, String toDirectory, FileFilter filter) throws IOException {
copyAndMergeFile(new File(formDirectory), new File(toDirectory), filter);
}
/**
* 把一个文件夹下的所有文件及其子文件夹下的文件,移动到另一个文件夹下
* @param fromDirectory
* @param toDirectory
*/
public static void copyAndMergeFile(File fromDirectory, File toDirectory, FileFilter filter) throws IOException {
if (!fromDirectory.isDirectory() || !toDirectory.isDirectory()) {
return;
}
File[] files = fromDirectory.listFiles();
if (files == null) {
return;
}
Scanner scanner = new Scanner(System.in);
for (File file : files) {
if (file.isFile()) {
// 过滤不合条件的文件
if (!filter.accept(file)) {
continue;
}
File copyFile = new File(toDirectory, file.getName());
if (copyFile.exists()) {
System.out.println(copyFile.getAbsoluteFile() + "已存在,是否覆盖?(Y/N)");
while (scanner.hasNext()) {
String next = scanner.next();
if ("Y".equals(next)) {
Files.copy(file.toPath(), copyFile.toPath());
break;
} else if ("N".equals(next)) {
break;
}
}
} else {
Files.copy(file.toPath(), copyFile.toPath());
}
} else if (file.isDirectory()) {
copyAndMergeFile(file, toDirectory, filter);
}
}
}
}
3. 遍历所有子文件夹找出重名文件
方法描述:在 C:UserszhangzeyuDesktop人脸识别整理照片 文件夹及其子文件夹下,找出所有重名的文件,并且列举出来。换言之,在不同子文件夹下,但是同名的文件将被列举出来。
使用场景:配合 方法2 找出存在合并风险的文件
注意点::在 Windows 系统中,a.jpg 和 a.JPG 在复制到同一文件夹下时,后复制进来的会覆盖先复制进来的。
import java.io.File;
import java.io.FileFilter;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.function.Function;
import java.util.stream.Collectors;
public class Main {
public static void main(String[] args) throws IOException {
Map<String, List<File>> sameNameFiles = findOutSameNameFile("C:\Users\zhangzeyu\Desktop\人脸识别整理\照片",
file -> file.getName().endsWith(".jpg") || file.getName().endsWith(".JPG"));
for (Map.Entry<String, List<File>> entry : sameNameFiles.entrySet()) {
System.out.println(entry.getKey() + ":");
for (File file : entry.getValue()) {
System.out.println(" " + file.getAbsolutePath());
}
}
}
public static Map<String, List<File>> findOutSameNameFile(String directory, FileFilter filter) throws IOException {
return findOutSameNameFile(new File(directory), filter);
}
/**
* 返回文件夹下的重名文件(包括在不同子文件夹下的重名文件)
* @param directory 文件夹
* @param filter
*/
public static Map<String, List<File>> findOutSameNameFile(File directory, FileFilter filter) throws IOException {
Map<String, List<File>> map = new HashMap<>();
findOutSameNameFile(directory, filter, fileName -> fileName.substring(0, fileName.lastIndexOf(".")), map);
return map.entrySet().stream()
.filter(entry -> entry.getValue() != null && entry.getValue().size() > 1)
.collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue));
}
private static void findOutSameNameFile(File fromDirectory, FileFilter filter, Function<String, String> mapper, Map<String, List<File>> map) throws IOException {
File[] files = fromDirectory.listFiles();
if (files == null) {
return;
}
for (File file : files) {
if (file.isFile()) {
// 过滤不合条件的文件
if (!filter.accept(file)) {
continue;
}
String name = mapper.apply(file.getName());
List<File> fileList = map.getOrDefault(name, new ArrayList<>());
fileList.add(file);
map.put(name, fileList);
} else if (file.isDirectory()) {
findOutSameNameFile(file, filter, mapper, map);
}
}
}
}
4.将所有的文件名格式化后输出
功能描述: 文件夹 C:UserszhangzeyuDesktop人脸识别整理照片一(3)班 下有 a.jpg, b.jpg, c.jpg, d.avi,期望输出结果 a,b,c
使用场景: 将指定文件夹下的目标文件摘出来,然后连接成字符串输出。
import java.io.File;
import java.io.FilenameFilter;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.function.Function;
public class Main {
public static void main(String[] args) throws IOException {
List<String> fileNames = getFileNames(
new File("C:\Users\zhangzeyu\Desktop\人脸识别整理\照片\一(3)班"),
(dir, name) -> name.endsWith(".jpg") || name.endsWith(".JPG"),
name -> name.substring(0, name.lastIndexOf(".")));
System.out.println(String.join(",", fileNames));
}
public static List<String> getFileNames(String destFile, FilenameFilter filter, Function<String, String> mapper) {
return getFileNames(new File(destFile), filter, mapper);
}
public static List<String> getFileNames(File destFile, FilenameFilter filter, Function<String, String> mapper) {
if (destFile.isFile()) {
return Collections.singletonList(destFile.getName());
}
File[] files = destFile.listFiles(filter);
if (files == null) {
return Collections.emptyList();
}
List<String> list = new ArrayList<>();
for (File file : files) {
list.add(mapper.apply(file.getName()));
}
return list;
}
}