1. 概述
本文将快速介绍在 Java 中创建文件的几种常用方法。我们会依次使用 NIO 的 Files
和 Path
类、传统的 File
和 FileOutputStream
类,以及第三方库 Google Guava 和 Apache Commons IO 来实现文件创建。
这些方法各有特点,适用于不同场景。掌握它们有助于你在实际开发中灵活选择,避免踩坑。
2. 环境准备
在所有示例中,我们统一使用一个常量来定义目标文件路径:
private final String FILE_NAME = "src/test/resources/fileToCreate.txt";
为了保证每个测试用例的独立性,我们在每次测试前后清理目标文件:
@AfterEach
@BeforeEach
public void cleanUpFiles() {
File targetFile = new File(FILE_NAME);
targetFile.delete();
}
✅ 这种做法能有效避免测试之间的干扰,是单元测试中的常见实践。
3. 使用 NIO Files.createFile()
最推荐的方式之一是使用 Java NIO 的 Files.createFile()
方法:
@Test
public void givenUsingNio_whenCreatingFile_thenCorrect() throws IOException {
Path newFilePath = Paths.get(FILE_NAME);
Files.createFile(newFilePath);
}
特点:
- ✅ 基于现代 NIO API,语义清晰
- ✅ 自动利用
Path
接口处理路径,更安全 - ❌ 如果文件已存在,会抛出异常
⚠️ 注意:如果目标文件已经存在,该方法会抛出 FileAlreadyExistsException
,而不是静默失败:
java.nio.file.FileAlreadyExistsException: src/test/resources/fileToCreate.txt
at sun.nio.fs.WindowsException.translateToIOException(WindowsException.java:81)
📌 适用场景:你希望明确知道文件是否被成功创建,且不希望覆盖已有文件时。
4. 使用 File.createNewFile()
这是传统 IO 包中最直接的方式:
@Test
public void givenUsingFile_whenCreatingFile_thenCorrect() throws IOException {
File newFile = new File(FILE_NAME);
boolean success = newFile.createNewFile();
assertTrue(success);
}
关键行为:
- ✅ 仅当文件不存在时创建,存在则返回
false
- ❌ 不抛异常,需手动检查返回值
- ⚠️ 方法是原子操作,适合多线程环境下的“首次创建”逻辑
📌 典型用途:实现简单的“锁文件”机制或确保某个配置文件只被初始化一次。
5. 使用 FileOutputStream
通过构造 FileOutputStream
实例也可以间接创建文件:
@Test
public void givenUsingFileOutputStream_whenCreatingFile_thenCorrect() throws IOException {
try (FileOutputStream fileOutputStream = new FileOutputStream(FILE_NAME)) {
// 文件在此时已被创建
}
}
行为说明:
- ✅ 文件不存在时自动创建
- ❌ 如果文件已存在,内容会被清空(覆盖)
- ❌ 若目标路径是目录或无权限,抛出
FileNotFoundException
- ✅ 使用 try-with-resources 确保资源释放
📌 风险提示:这种方式容易误删已有数据,使用时务必确认业务逻辑是否允许覆盖。
6. 使用 Guava
Google Guava 提供了极为简洁的工具方法:
@Test
public void givenUsingGuava_whenCreatingFile_thenCorrect() throws IOException {
com.google.common.io.Files.touch(new File(FILE_NAME));
}
优势:
- ✅ 一行代码搞定
- ✅ 若文件已存在,仅更新时间戳,不报错
- ✅ 支持递归创建父目录
📌 适合场景:脚本化任务、临时文件初始化等对健壮性要求高的地方。
7. 使用 Apache Commons IO
Apache Commons IO 同样提供了类似功能:
@Test
public void givenUsingCommonsIo_whenCreatingFile_thenCorrect() throws IOException {
FileUtils.touch(new File(FILE_NAME));
}
行为特点:
- ✅ 功能与 Guava 的
touch
基本一致 - ✅ 自动创建缺失的父目录
- ✅ 文件存在时不报错,仅更新最后修改时间
📌 对比建议:
- 如果项目已引入 Commons IO,优先使用
FileUtils.touch()
- 否则不必为了一个功能引入新依赖
8. 总结
方法 | 是否覆盖 | 异常处理 | 是否创建父目录 | 推荐指数 |
---|---|---|---|---|
Files.createFile() |
❌ 抛异常 | ✅ 明确 | ❌ 需手动 | ⭐⭐⭐⭐ |
File.createNewFile() |
❌ 返回 false | ❌ 需判断 | ❌ | ⭐⭐⭐ |
FileOutputStream |
✅ 覆盖 | ✅ 抛异常 | ❌ | ⭐⭐⭐ |
Guava Files.touch() |
❌ 不覆盖 | ✅ 安静处理 | ✅ | ⭐⭐⭐⭐⭐ |
Commons IO FileUtils.touch() |
❌ 不覆盖 | ✅ 安静处理 | ✅ | ⭐⭐⭐⭐⭐ |
最终建议:
- 日常开发中,✅ 优先考虑 Guava 或 Commons IO 的
touch
方法,简单粗暴又安全。 - 若不能引入第三方库,使用
Files.createFile()
+Files.createDirectories()
组合也能达到类似效果。
示例代码已托管至 GitHub:https://github.com/baeldung/java-tutorials(模块:core-java-io-3)