395. Java 文件操作基础 - 读写小文件

32 阅读2分钟

395. Java 文件操作基础 - 读写小文件

在 Java 的文件 I/O API 中,Files 工具类为我们提供了多种读写文件的方式。不同方法适用于不同场景。我们要学会“对症下药”,选择合适的方法。


1️⃣ 如何选择合适的 I/O 方法?

下面的表格总结了常见方法及使用场景:

读取写入适用场景 / 说明
readAllBytes() readAllLines()write()最简单的用法:一次性读入或写出小文件(几 KB ~ 几 MB)。
newBufferedReader()newBufferedWriter()逐行处理文本:适合处理大文本文件,避免一次性加载。
newInputStream()newOutputStream()兼容 java.io:适合需要与传统 I/O 代码(如 InputStreamOutputStream)交互的场景。
newByteChannel() SeekableByteChannel ByteBuffer——高阶操作:适合随机访问文件,或需要 NIO 特性(非阻塞 I/O)。
FileChannel——高级应用:文件锁、内存映射(Memory-Mapped I/O),通常用于大文件处理。

2️⃣ 常见示例

🔹 读取整个文件内容

Path file = Paths.get("data.txt");

// 方式1:一次性读入所有字节(适合小文件)
byte[] bytes = Files.readAllBytes(file);
String content = new String(bytes, StandardCharsets.UTF_8);

// 方式2:一次性读入所有行
List<String> lines = Files.readAllLines(file, StandardCharsets.UTF_8);
lines.forEach(System.out::println);

👉 适用场景:配置文件、小日志文件、测试数据。


🔹 写入小文件

Path file = Paths.get("output.txt");
String content = "Hello, world!";

// 一次性写入
Files.write(file, content.getBytes(StandardCharsets.UTF_8));

👉 适用场景:快速保存结果文件、配置导出。


🔹 使用 BufferedReader / BufferedWriter(逐行读写)

Path file = Paths.get("data.txt");

// 逐行读取
try (BufferedReader reader = Files.newBufferedReader(file, StandardCharsets.UTF_8)) {
    String line;
    while ((line = reader.readLine()) != null) {
        System.out.println(line);
    }
}

// 写入文件(逐行)
try (BufferedWriter writer = Files.newBufferedWriter(file, StandardCharsets.UTF_8)) {
    writer.write("Line 1");
    writer.newLine();
    writer.write("Line 2");
}

👉 适用场景:大文件(避免一次性加载到内存)、日志分析、逐行转换。


🔹 使用 InputStream / OutputStream(兼容 java.io)

Path file = Paths.get("image.png");

// 读
try (InputStream in = Files.newInputStream(file)) {
    byte[] buffer = new byte[1024];
    int bytesRead;
    while ((bytesRead = in.read(buffer)) != -1) {
        System.out.println("Read " + bytesRead + " bytes");
    }
}

// 写
try (OutputStream out = Files.newOutputStream(Paths.get("copy.png"))) {
    out.write(Files.readAllBytes(file));
}

👉 适用场景:和旧的 java.io 代码兼容,二进制文件处理(图片、视频)。


3️⃣ 进阶:文件属性(POSIX)

创建文件时,可以指定初始属性,例如文件所有者、组、权限(仅支持 POSIX 文件系统,如 Linux / macOS)。

Set<PosixFilePermission> perms = PosixFilePermissions.fromString("rw-r-----");
FileAttribute<Set<PosixFilePermission>> attr = PosixFilePermissions.asFileAttribute(perms);

Path file = Files.createFile(Paths.get("secure.txt"), attr);

👉 在安全敏感的场景(如日志、证书文件),可以确保文件一开始就有合适的权限。


🎯 总结

  • 小文件 → readAllBytes() / write()(最简单,适合小数据)。
  • 大文件 → BufferedReader / BufferedWriter(逐行处理)。
  • 二进制 / 与老代码兼容 → InputStream / OutputStream
  • 高性能 / 特殊需求 → FileChannelByteBuffer、文件锁、内存映射
  • POSIX 属性 → createFile() 时传入 FileAttribute

👉 记住一句话:根据文件大小和用途选择 API,不要“无脑全用 readAllBytes()”,否则可能会内存爆炸 💥。