396. Java 文件操作基础 - OpenOptions 参数详解
在 Java NIO.2 的文件操作中,很多方法都会带一个可选的 OpenOption 参数。
👉 这个参数不是必须的,如果你不传,API 会有默认行为。
👉 如果你需要特殊行为,比如 追加写入、同步写入、创建新文件,就需要传入不同的 StandardOpenOption 枚举值。
1️⃣ 可变参数(Varargs)
你会注意到,很多 Files 类的方法都有这样的签名:
Files.newOutputStream(path, StandardOpenOption... options)
这里的 ...(省略号)表示 可变参数。
-
你可以传 一个值:
Files.newOutputStream(path, StandardOpenOption.CREATE); -
也可以传 多个值:
Files.newOutputStream(path, StandardOpenOption.CREATE, StandardOpenOption.APPEND); -
或者直接传 一个数组:
StandardOpenOption[] opts = {StandardOpenOption.CREATE, StandardOpenOption.APPEND}; Files.newOutputStream(path, opts);
2️⃣ 常见的 OpenOption 枚举 🚀
| 枚举值 | 含义 | 说明 |
|---|---|---|
WRITE | 以写入模式打开文件 | 不能单独用于新文件,需结合 CREATE |
APPEND | 在文件末尾追加内容 | 常和 WRITE 或 CREATE 一起用 |
TRUNCATE_EXISTING | 截断文件为 0 字节 | 相当于清空文件再写入 |
CREATE_NEW | 创建新文件 | 如果文件已存在就报错 |
CREATE | 文件存在就打开,不存在就创建 | 常见的“自动创建”场景 |
DELETE_ON_CLOSE | 关闭流时删除文件 | 常用于临时文件 |
SPARSE | 提示文件系统使用稀疏文件优化存储 | 一般只在 NTFS 等支持的文件系统生效 |
SYNC | 数据和元数据同步写入磁盘 | 适合需要强一致性的场景 |
DSYNC | 仅文件数据同步写入磁盘 | 比 SYNC 更快,但元数据可能延迟 |
3️⃣ 示例代码讲解 📝
(1)普通写入
Path path = Paths.get("example.txt");
try (OutputStream out = Files.newOutputStream(path, StandardOpenOption.CREATE, StandardOpenOption.WRITE)) {
out.write("Hello, Java NIO!".getBytes());
}
👉 如果 example.txt 不存在,就创建;如果存在,就覆盖。
(2)追加写入
Path path = Paths.get("example.txt");
try (OutputStream out = Files.newOutputStream(path, StandardOpenOption.CREATE, StandardOpenOption.APPEND)) {
out.write("\nNew line appended!".getBytes());
} catch (IOException e) {
e.printStackTrace();
}
👉 文件存在就追加,不存在就创建新文件。
(3)临时文件写入并自动删除
Path temp = Files.createTempFile("test", ".txt");
try (OutputStream out = Files.newOutputStream(temp, StandardOpenOption.DELETE_ON_CLOSE)) {
out.write("Temporary content".getBytes());
System.out.println("写入临时文件: " + temp);
}
System.out.println("文件已关闭并自动删除");
👉 常用于缓存文件、测试日志,避免磁盘垃圾。
(4)强一致性写入
Path path = Paths.get("important.log");
try (OutputStream out = Files.newOutputStream(path, StandardOpenOption.CREATE, StandardOpenOption.WRITE, StandardOpenOption.SYNC)) {
out.write("Critical transaction log\n".getBytes());
}
👉 保证日志内容 立即落盘,哪怕断电也不会丢。
4️⃣ 类比 🌟
APPEND就像在笔记本最后一页继续写字。TRUNCATE_EXISTING就像把笔记本的内容全撕掉,从第一页重新写。CREATE_NEW就像买一本新笔记本,旧的不能复用。DELETE_ON_CLOSE就像写在白板上,下课一关门自动擦掉。SYNC和DSYNC就像你写日记:SYNC= 写好内容再把日期、时间、封面都登记上。DSYNC= 只写正文,封面可能晚点补。
📌 完整示例:OpenOption 全家桶
import java.io.OutputStream;
import java.nio.file.*;
import java.nio.charset.StandardCharsets;
public class OpenOptionDemo {
public static void main(String[] args) throws Exception {
Path baseDir = Paths.get("demo_files");
Files.createDirectories(baseDir); // 创建演示目录
// 1️⃣ 普通写入 (CREATE + WRITE + TRUNCATE_EXISTING)
Path file1 = baseDir.resolve("file1.txt");
try (OutputStream out = Files.newOutputStream(file1,
StandardOpenOption.CREATE,
StandardOpenOption.WRITE,
StandardOpenOption.TRUNCATE_EXISTING)) {
out.write("Hello, Java NIO!\n".getBytes(StandardCharsets.UTF_8));
}
System.out.println("写入 file1.txt,若存在则清空后写入。");
// 2️⃣ 追加写入 (CREATE + APPEND)
try (OutputStream out = Files.newOutputStream(file1,
StandardOpenOption.CREATE,
StandardOpenOption.APPEND)) {
out.write("New line appended!\n".getBytes(StandardCharsets.UTF_8));
}
System.out.println("追加写入 file1.txt。");
// 3️⃣ CREATE_NEW (只允许新文件)
Path file2 = baseDir.resolve("file2.txt");
try (OutputStream out = Files.newOutputStream(file2,
StandardOpenOption.CREATE_NEW,
StandardOpenOption.WRITE)) {
out.write("This file is new!\n".getBytes(StandardCharsets.UTF_8));
}
System.out.println("创建新文件 file2.txt,若已存在会报错。");
// 4️⃣ DELETE_ON_CLOSE (临时文件自动删除)
Path tempFile = baseDir.resolve("temp.txt");
try (OutputStream out = Files.newOutputStream(tempFile,
StandardOpenOption.CREATE,
StandardOpenOption.WRITE,
StandardOpenOption.DELETE_ON_CLOSE)) {
out.write("Temporary content\n".getBytes(StandardCharsets.UTF_8));
System.out.println("写入临时文件 temp.txt,关闭流后文件会被删除。");
}
System.out.println("temp.txt 已关闭并删除。");
// 5️⃣ SYNC (强一致性写入)
Path file3 = baseDir.resolve("file3.log");
try (OutputStream out = Files.newOutputStream(file3,
StandardOpenOption.CREATE,
StandardOpenOption.WRITE,
StandardOpenOption.SYNC)) {
out.write("Critical log entry\n".getBytes(StandardCharsets.UTF_8));
}
System.out.println("写入 file3.log,并保证内容立即同步到磁盘。");
System.out.println("\n✅ 演示完成!请查看 demo_files 目录。");
}
}