Skip to content

文件创建、删除、重命名

只需三步:创建、使用、删除。

这一节讲清楚文件 CRUD 的标准操作。

创建文件

File.createNewFile()

java
File f = new File("newfile.txt");

// ✅ 正确
if (!f.exists()) {
    f.createNewFile();
}

// ❌ 不检查 exists() 会抛异常
f.createNewFile(); // 文件已存在抛异常

Files.createFile()

java
Path p = Path.of("newfile.txt");
try {
    Files.createFile(p);
} catch (FileAlreadyExistsException e) {
    // 文件已存在
}

创建目录

java
// 单层目录
new File("mydir").mkdir();
Files.createDirectory(Path.of("mydir"));

// 多层目录
new File("a/b/c").mkdirs();
Files.createDirectories(Path.of("a/b/c"));

删除

java
// File.delete()
File f = new File("file.txt");
f.delete();                         // 返回 boolean
f.deleteOnExit();                   // JVM 退出时删除

// Files.delete()
Files.delete(Path.of("file.txt"));   // 不存在抛异常
Files.deleteIfExists(Path.of("file.txt")); // 不存在不抛异常

重命名 / 移动

java
// File.renameTo()
File oldFile = new File("old.txt");
File newFile = new File("new.txt");
oldFile.renameTo(newFile); // 返回 boolean

// 可以跨目录移动
File toMove = new File("old/dir/file.txt");
File moved = new File("new/dir/file.txt");
toMove.renameTo(moved); // 移动并重命名

// Files.move()
Files.move(Path.of("old.txt"), Path.of("new.txt"));
Files.move(Path.of("old.txt"), Path.of("new/dir/new.txt"),
    StandardCopyOption.REPLACE_EXISTING);

批量操作

批量创建目录

java
public static void createDirectories(String basePath, List<String> dirs) {
    for (String dir : dirs) {
        Path path = Path.of(basePath, dir);
        try {
            Files.createDirectories(path);
            System.out.println("创建: " + path);
        } catch (IOException e) {
            System.err.println("创建失败: " + path);
        }
    }
}

批量删除

java
public static void deleteFiles(List<Path> paths) {
    for (Path p : paths) {
        try {
            Files.deleteIfExists(p);
            System.out.println("删除: " + p);
        } catch (IOException e) {
            System.err.println("删除失败: " + p);
        }
    }
}

批量移动

java
public static void moveFiles(Path srcDir, Path dstDir, String suffix) {
    try (Stream<Path> stream = Files.list(srcDir)) {
        stream.filter(p -> p.toString().endsWith(suffix))
              .forEach(p -> {
                  Path dst = dstDir.resolve(p.getFileName());
                  try {
                      Files.move(p, dst, StandardCopyOption.REPLACE_EXISTING);
                      System.out.println("移动: " + p + " -> " + dst);
                  } catch (IOException e) {
                      System.err.println("移动失败: " + p);
                  }
              });
    }
}

常见问题

目录不存在

java
// 创建文件时,父目录不存在会抛异常
Files.createFile(Path.of("nonexistent/file.txt")); // NoSuchFileException

// ✅ 先创建目录
Path filePath = Path.of("nonexistent/file.txt");
Files.createDirectories(filePath.getParent());
Files.createFile(filePath);

删除失败

java
// ❌ 删除失败可能因为:
// 1. 文件不存在
// 2. 目录非空
// 3. 没有权限
// 4. 文件被占用

Files.delete(Path.of("file.txt")); // 可能抛异常
Files.deleteIfExists(Path.of("file.txt")); // 更安全

// ✅ 删除非空目录需要递归
public static void deleteRecursively(Path path) throws IOException {
    if (Files.isDirectory(path)) {
        try (Stream<Path> entries = Files.list(path)) {
            for (Path entry : entries.toList()) {
                deleteRecursively(entry);
            }
        }
    }
    Files.delete(path);
}

总结

┌─────────────────────────────────────────────────────────────────┐
│  文件 CRUD 口诀:                                                 │
│                                                                 │
│  创建前检查 exists()                                              │
│  创建时用 mkdirs()(支持多层)                                     │
│  删除用 deleteIfExists()(更安全)                                │
│  移动用 Files.move()(支持跨目录)                                │
└─────────────────────────────────────────────────────────────────┘

基于 VitePress 构建