396. Java 文件操作基础 - OpenOptions 参数详解

0 阅读3分钟

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在文件末尾追加内容常和 WRITECREATE 一起用
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 就像写在白板上,下课一关门自动擦掉。
  • SYNCDSYNC 就像你写日记:
    • 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 目录。");
    }
}