讲解
程序的数据存在内存里,进程一结束就没了;要持久保存就得读写文件。JDK 7 引入的 NIO.2(java.nio.file 包)把文件操作收敛成三个主角:Path 表示路径(用 Path.of("data.txt") 创建,告别字符串拼路径)、Paths 工厂、Files 工具类——读、写、复制、删除、判断存在等操作都是 Files 的静态方法,入门阶段掌握它就够了,老教程里的 File、FileReader 那套知道是历史即可。
读写小文件极其简单:Files.writeString(path, 内容) 一次写入整个字符串(默认 UTF-8),Files.readString(path) 一次读出全部文本;按行处理用 Files.write(path, 行列表) 和 Files.readAllLines(path)。写文件默认覆盖已存在的文件,想追加内容传 StandardOpenOption.APPEND。文件不存在就读会抛 NoSuchFileException,先用 Files.exists(path) 判断是稳妥习惯。
文件操作抛的都是受检异常 IOException,必须处理:方法上 throws 或 try...catch 接住。涉及逐行读写大文件时用 BufferedReader/BufferedWriter 配合 try-with-resources,处理大文件不要一次 readString 把整个文件吞进内存。路径拼接用 path.resolve("子路径"),判断类型用 Files.isDirectory / Files.isRegularFile,列目录用 Files.list——它们共同构成日常文件操作的最小工具箱。
示例
写入字符串再整体读出,覆盖与追加两种模式:
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.StandardOpenOption;
public class Main {
public static void main(String[] args) throws Exception {
Path file = Path.of("notes.txt");
Files.writeString(file, "第一行笔记\n第二行笔记\n");
System.out.println("写入完成,文件存在?" + Files.exists(file));
Files.writeString(file, "追加的一行\n", StandardOpenOption.APPEND);
String content = Files.readString(file);
System.out.println("--- 文件内容 ---");
System.out.print(content);
System.out.println("文件大小:" + Files.size(file) + " 字节");
}
}
按行读写:写入行列表、读回逐行编号、读前判断存在:
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.List;
public class Main {
public static void main(String[] args) throws Exception {
Path file = Path.of("todo.txt");
List<String> tasks = List.of("写周报", "复习泛型", "跑步三公里");
Files.write(file, tasks);
if (Files.exists(file)) {
List<String> lines = Files.readAllLines(file);
for (int i = 0; i < lines.size(); i++) {
System.out.println((i + 1) + ". " + lines.get(i));
}
}
Files.delete(file);
System.out.println("清理完成,文件还在?" + Files.exists(file));
}
}
常见坑
- 用字符串 + 拼路径:"dir" + "/" + name 在 Windows 上分隔符不同就出岔子。用 Path.of("dir", name) 或 path.resolve(name),交给库处理分隔符。
- 不处理 IOException 就编译不过:文件方法是受检异常,throws 或 catch 二选一。入门示例常用 throws Exception,真实代码里应该 catch 并给出有意义的处理。
- 一次 readString 读大文件:几个 GB 的文件整个装进内存直接 OOM。大文件逐行处理:Files.newBufferedReader 或 Files.lines(记得 try-with-resources)。
- 以为 writeString 会追加:默认是覆盖!想追加必须显式传 StandardOpenOption.APPEND,老内容被悄悄覆盖是高频事故。
小结
Path 表示路径,Files 一行读写小文件;默认覆盖、追加用 APPEND,IO 异常必须处理,大文件逐行来。下一节学习让程序同时做多件事:多线程基础。