CodeGym /课程 /JAVA 25 SELF /创建与删除文件和目录

创建与删除文件和目录

JAVA 25 SELF
第 40 级 , 课程 0
可用

1. 创建文件

在程序中创建文件是很常见的需求:用于日志、临时数据、报表导出、数据导入、保存设置等。在 Java 中,正如你可能已经猜到的,最好使用现代 API——java.nio.file

核心工具:Files.createFile(Path)

该方法按给定路径创建新文件。若文件已存在,将抛出异常。

示例:在当前目录创建一个文本文件

import java.nio.file.*;

public class CreateFileExample {
    public static void main(String[] args) {
        Path path = Path.of("hello.txt");
        try {
            Files.createFile(path);
            System.out.println("文件已创建:" + path.toAbsolutePath());
        } catch (FileAlreadyExistsException e) {
            System.out.println("文件已存在:" + path);
        } catch (Exception e) {
            System.out.println("创建文件时出错:" + e.getMessage());
        }
    }
}

请注意:
Files.createFile 会在文件已存在时抛出 FileAlreadyExistsException。因此常在创建前检查文件是否存在。

检查文件是否存在

Path path = Path.of("hello.txt");
if (!Files.exists(path)) {
    Files.createFile(path);
}

提示:
检查是否存在并不能防止并发竞态,但对大多数用户场景来说已经足够实用。

简述:创建文件时会发生什么?

  • 如果文件不存在且路径有效——将创建一个新的空文件。
  • 如果文件已存在——会抛出异常。
  • 如果路径无效、无权限或目录不存在——会抛出其他异常(如 IOExceptionNoSuchFileException 等)。

2. 创建目录

Files.createDirectoryFiles.createDirectories 的区别

  • Files.createDirectory(Path) —— 仅创建一个目录。若父目录不存在——会报错。
  • Files.createDirectories(Path) —— 会创建缺失的整条目录链(就像一个魔法师在你脚下现搭楼梯)。

示例:创建单个目录

Path dir = Path.of("data");
try {
    Files.createDirectory(dir);
    System.out.println("目录已创建:" + dir.toAbsolutePath());
} catch (FileAlreadyExistsException e) {
    System.out.println("目录已存在:" + dir);
} catch (Exception e) {
    System.out.println("创建目录时出错:" + e.getMessage());
}

示例:创建嵌套目录结构

Path nested = Path.of("data/reports/2024");
try {
    Files.createDirectories(nested);
    System.out.println("目录结构已创建:" + nested.toAbsolutePath());
} catch (Exception e) {
    System.out.println("创建结构时出错:" + e.getMessage());
}

请注意:如果某些目录已经存在,createDirectories 并不介意——它只会创建缺失的部分。若对嵌套目录使用 createDirectory 而父目录尚不存在——会报错。

表格:创建目录方法对比

方法 仅创建单个目录 可创建嵌套目录 部分已存在时不报错
createDirectory
createDirectories

3. 删除文件

删除文件就像倒垃圾:关键是别把需要的东西扔了!在 Java 中主要有两种方法:

  • Files.delete(Path) —— 删除文件或空目录。若目标不存在——会抛出异常。
  • Files.deleteIfExists(Path) —— 删除文件,但如果目标不存在——静默无操作。

示例:删除临时文件

Path tempFile = Path.of("temp.txt");
try {
    Files.delete(tempFile);
    System.out.println("文件已删除:" + tempFile);
} catch (NoSuchFileException e) {
    System.out.println("未找到文件:" + tempFile);
} catch (DirectoryNotEmptyException e) {
    System.out.println("目录非空:" + tempFile);
} catch (Exception e) {
    System.out.println("删除时出错:" + e.getMessage());
}

更安全的做法

boolean deleted = Files.deleteIfExists(tempFile);
if (deleted) {
    System.out.println("文件已被删除。");
} else {
    System.out.println("未找到文件——无需删除。");
}

重要!

  • 如果文件正被其他程序打开,可能会抛出异常(例如在 Windows 上)。
  • 若尝试删除非空目录,将抛出 DirectoryNotEmptyException

4. 删除目录

在 Java 中删除目录与删除文件相似。但有个细节:标准方法只能删除 目录。

示例:删除空目录

Path emptyDir = Path.of("empty_folder");
try {
    Files.delete(emptyDir);
    System.out.println("目录已删除:" + emptyDir);
} catch (DirectoryNotEmptyException e) {
    System.out.println("目录非空:" + emptyDir);
} catch (NoSuchFileException e) {
    System.out.println("未找到目录:" + emptyDir);
} catch (Exception e) {
    System.out.println("删除目录时出错:" + e.getMessage());
}

非空目录怎么办?

要删除非空目录,需要递归删除其内所有文件和子目录。这值得单独一讲(也是一次小冒险),但如果你已经迫不及待,请看下面的代码,理解并尝试复现:

import java.nio.file.*;
import java.io.IOException;

public class DeleteDirectoryRecursively {
    public static void deleteRecursively(Path path) throws IOException {
        if (Files.isDirectory(path)) {
            try (var entries = Files.list(path)) {
                for (Path entry : entries.toList()) {
                    deleteRecursively(entry);
                }
            }
        }
        Files.delete(path);
    }
}

注意:
这段代码会删除目录中的一切!请谨慎使用。

5. 实践建议

删除前先检查是否存在

if (Files.exists(path)) {
    Files.delete(path);
} else {
    System.out.println("文件/目录不存在。");
}

但如果使用 deleteIfExists,就没必要这样做。

处理异常

处理文件时经常会遇到各种意外。为此 Java 会抛出不同类型的异常:

  • NoSuchFileException —— 文件或目录未找到。例如你尝试打开已删除的对象。
  • DirectoryNotEmptyException —— 你想删除目录,但里面还有内容。
  • IOException —— 通用告警:出了点问题。可能原因很多——无访问权限、文件被其他程序占用、路径不正确。

可视化示意:核心方法

+-------------------+         +--------------------+
| Files.createFile  | ---->   |     新文件         |
+-------------------+         +--------------------+

+---------------------+       +--------------------+
| Files.createDirectory|----> |     新目录         |
+---------------------+       +--------------------+

+-------------------+         +--------------------+
| Files.delete      | ---->   |  文件/目录已删除   |
+-------------------+         +--------------------+

(但前提是目录为空!)

6. 创建与删除文件和目录的常见错误

错误 1:尝试创建已存在的文件/目录。 Files.createFileFiles.createDirectory 在对象已存在时会抛出异常。解决方案——提前检查是否存在或捕获异常。

错误 2:使用 createDirectory 创建嵌套目录,但父目录尚不存在。 此时会抛出 NoSuchFileException。请使用 createDirectories 来创建目录链。

错误 3:尝试通过 Files.delete 删除非空目录。 会得到 DirectoryNotEmptyException。删除非空目录需要递归。

错误 4:没有在指定目录中创建/删除的权限。 将抛出 AccessDeniedExceptionIOException。以所需权限运行程序或使用可访问的目录。

错误 5:文件被其他进程占用。 在 Windows(以及有时其他操作系统)上,如果文件被其他程序打开,将无法删除。你会得到 IOException。请在删除前关闭所有使用该文件的应用。

错误 6:在不清楚“当前工作目录”时使用相对路径。 文件会被创建在与你预期不同的位置。为了确定,请使用 toAbsolutePath() 并将路径打印出来。

评论
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION