不能继续用 File 拼路径,因其硬拼字符串易出错(如 Windows 反斜杠转义)、跨文件系统操作失败静默、路径处理能力弱;Path+Files 提供平台适配、符号链接支持、原子操作、流式读写等 File 不具备的核心能力。

为什么不能继续用 File 拼路径?
不是“不推荐”,而是硬拼字符串在真实项目里大概率出错:new File("C:\temp\log.txt") 在 Windows 下反斜杠被当转义符,实际变成 C: emp\log.txt,路径错乱却无任何异常;file.renameTo(another) 跨文件系统失败时只返回 false,不抛异常,逻辑卡死难排查。
- 用
Paths.get("a", "b", "c")自动适配平台分隔符(Windows 用\,Unix 用/) - 拼路径必须用
p.resolve("sub"),不是p.toString() + "/sub" - 消除冗余路径段:用
p.normalize()把a/../b变成b,避免isDirectory()判断失败
Files.exists() 和 file.exists() 行为完全不同
Files.exists(p) 是 NIO 语义的、可预测的检查:它统一抛 NoSuchFileException(继承自 IOException),对符号链接行为一致;而 file.exists() 是老式黑盒判断,遇到符号链接可能返回 false 却不告诉你原因,且不区分“不存在”和“无权限访问”。
- 检查前先确认是普通文件:
Files.isRegularFile(p),比file.isFile()更可靠 - 要读配置文件,别只看
exists(),还得加Files.isReadable(p)和Files.isRegularFile(p) - 永远别写
p.toFile().exists()—— 这等于绕过 NIO,重蹈旧坑
哪些操作 File 根本做不到,只能靠 Path+Files?
不是“更方便”,而是能力断层:File 类没有等价实现,某些需求下它就是无解。
- 处理符号链接:
Files.isSymbolicLink(p)判断,Files.readSymbolicLink(p)读目标路径 - 一次取多个属性:
Files.readAttributes(p, "basic:size,lastModifiedTime,creationTime"),比反复调file.length()+file.lastModified()更高效、线程安全 - 可控深度遍历:
Files.walk(p, 3)限制递归最多 3 层;Files.list(p)仅当前层,配合Files.isDirectory(p)自定义过滤 - 原子移动:
Files.move(src, dst, ATOMIC_MOVE)在 ext4/NTFS 上真能避免写一半崩溃导致数据残缺
小文件读写怎么写才不出乱码、不爆内存?
Files.readString(p, UTF_8)(Java 11+)强制指定编码,杜绝 FileUtils.readFileToString() 默认用系统编码导致的乱码;但注意:Files.readAllLines(p) 和 Files.readAllBytes(p) 会一次性加载全部内容到内存。
立即学习“Java免费学习笔记(深入)”;
- 读 >100MB 文本:必须改用
Files.lines(p)流式读取,或Files.newInputStream(p)配合缓冲区 - 写入追加:显式传
StandardOpenOption.APPEND,别依赖默认覆盖行为 - 创建目录优先用
Files.createDirectories(p)(自动建多级父目录),不是Files.createDirectory(p)(父目录不存在就抛异常)
exists()、size()、readAllLines(),其实都是 Files 类干的——你得习惯把路径构造和 I/O 分开想。










