Path 和 Files 工具类
JDK 7 引入了 Path 和 Files,是对 File 类的现代化替代。
这一节讲清楚它们的新增 API 和改进之处。
Path:更现代的路径表示
创建 Path
java
// 方式 1:Path.of()(JDK 11+)
Path p1 = Path.of("dir/subdir/file.txt");
Path p2 = Path.of("dir", "subdir", "file.txt");
// 方式 2:Paths.get()
Path p3 = Paths.get("dir", "subdir", "file.txt");
// 方式 3:从 File 转换
Path p4 = new File("test.txt").toPath();
File f = p4.toFile();路径操作
java
Path p = Path.of("dir/subdir/file.txt");
p.getFileName(); // "file.txt"
p.getParent(); // "dir/subdir"
p.getRoot(); // "/"(Linux/macOS)或 "C:\\"(Windows)
p.isAbsolute(); // false
p.toAbsolutePath(); // 绝对路径
p.getNameCount(); // 3(路径段数)
p.getName(0); // "dir"
p.getName(1); // "subdir"
p.getName(2); // "file.txt"
p.subpath(1, 3); // "subdir/file.txt"路径解析
java
Path p = Path.of("dir/subdir/file.txt");
// 拼接
Path resolved = p.resolve("sibling.txt"); // "dir/subdir/sibling.txt"
Path resolved2 = p.resolveSibling("other.txt"); // "dir/other.txt"
// 相对路径
Path p1 = Path.of("dir/file.txt");
Path p2 = Path.of("dir/sub/file2.txt");
Path relative = p2.relativize(p1); // "../file.txt"
// 规范化
Path normalized = Path.of("dir/../dir/file.txt").normalize(); // "dir/file.txt"Files:文件工具类
Files 是 NIO 的核心工具类,提供大量静态方法。
判断方法
java
Files.exists(path); // 是否存在
Files.notExists(path); // 是否不存在
Files.isRegularFile(path); // 是否是普通文件
Files.isDirectory(path); // 是否是目录
Files.isSymbolicLink(path); // 是否是符号链接
Files.isReadable(path); // 是否可读
Files.isWritable(path); // 是否可写
Files.isExecutable(path); // 是否可执行读取文件
java
// 读取全部(一次性读入内存,适合小文件)
byte[] bytes = Files.readAllBytes(Path.of("file.bin"));
String content = Files.readString(Path.of("file.txt")); // JDK 11+,默认 UTF-8
String content = Files.readString(Path.of("file.txt"), StandardCharsets.UTF_8);
// 按行读取
List<String> lines = Files.readAllLines(Path.of("file.txt"), StandardCharsets.UTF_8);
// 流式处理行(大文件)
try (Stream<String> stream = Files.lines(Path.of("file.txt"))) {
stream.filter(line -> line.length() > 10)
.forEach(System.out::println);
}写入文件
java
// 写入字节数组或字符串
Files.write(Path.of("out.txt"), "hello".getBytes());
Files.writeString(Path.of("out.txt"), "hello"); // JDK 11+
// 追加模式
Files.write(Path.of("out.txt"), "append".getBytes(),
StandardOpenOption.APPEND);
// 写入多行
List<String> lines = List.of("第一行", "第二行");
Files.write(Path.of("out.txt"), lines, StandardCharsets.UTF_8);
// 逐行写入
try (BufferedWriter writer = Files.newBufferedWriter(Path.of("out.txt"))) {
for (String line : lines) {
writer.write(line);
writer.newLine();
}
}创建与删除
java
// 创建文件
Files.createFile(Path.of("new.txt"));
// 创建目录
Files.createDirectory(Path.of("mydir")); // 单层
Files.createDirectories(Path.of("a/b/c")); // 多层
// 删除
Files.delete(Path.of("file.txt")); // 不存在抛异常
Files.deleteIfExists(Path.of("file.txt")); // 不存在不抛异常复制与移动
java
// 复制
Files.copy(Path.of("src.txt"), Path.of("dst.txt"));
Files.copy(Path.of("src.txt"), Path.of("dst.txt"),
StandardCopyOption.REPLACE_EXISTING); // 覆盖
// 移动(重命名)
Files.move(Path.of("old.txt"), Path.of("new.txt"));
Files.move(Path.of("old.txt"), Path.of("new/dir/new.txt"),
StandardCopyOption.REPLACE_EXISTING);遍历目录
java
// walk:深度优先遍历
try (Stream<Path> stream = Files.walk(Path.of("mydir"))) {
stream.forEach(System.out::println);
}
// list:只遍历一层
try (Stream<Path> stream = Files.list(Path.of("mydir"))) {
stream.filter(p -> p.toString().endsWith(".txt"))
.forEach(System.out::println);
}
// find:带条件过滤
try (Stream<Path> stream = Files.find(Path.of("mydir"),
10, // 最大深度
(p, a) -> p.toString().endsWith(".txt") && a.size() > 1024)) {
stream.forEach(System.out::println);
}文件属性
java
Files.size(path); // 文件大小
Files.getLastModifiedTime(path); // 最后修改时间
Files.setLastModifiedTime(path, time); // 设置修改时间
BasicFileAttributes attr = Files.readAttributes(path, BasicFileAttributes.class);
attr.creationTime(); // 创建时间
attr.lastModifiedTime(); // 修改时间
attr.size(); // 大小
attr.isDirectory(); // 是否目录临时文件/目录
java
// 创建临时文件
Path tempFile = Files.createTempFile("prefix", ".tmp");
Path tempFile2 = Files.createTempFile(null, ".tmp"); // 无前缀
// 创建临时目录
Path tempDir = Files.createTempDirectory("mytempdir");
// 使用完自动删除
tempFile.toFile().deleteOnExit();File vs Path/Files
| 对比 | File | Path / Files |
|---|---|---|
| JDK 版本 | JDK 1.0 | JDK 7+ |
| API | 分散在多个方法 | 静态工具类 |
| 路径表示 | File 对象 | Path 接口 |
| 功能 | 少 | 更丰富 |
| 推荐 | 不推荐 | 推荐 |
选型建议
┌─────────────────────────────────────────────────────────────────┐
│ 新代码用 Path / Files,旧代码慢慢迁移 │
│ │
│ Files 是工具类,Path 是路径表示 │
│ File 是历史遗留,但它还没消失 │
└─────────────────────────────────────────────────────────────────┘