File.exists() 仅判断路径存在性,不区分文件/目录且不校验权限;应配合 canRead()/canWrite()、isFile() 使用,JDK7+推荐Files.exists()替代。

File.exists() 判断不准?别直接信返回值
Java 的 File.exists() 只检查路径是否“存在”,但不区分是文件还是目录,也不校验读写权限。常见错误是用它判断“文件能否被读取”,结果调用 FileReader 时抛出 FileNotFoundException 或 SecurityException。
- 先调用
exists(),再用canRead()或canWrite()补充校验权限 - 对目录路径,
exists()返回true时,isFile()会是false—— 别漏掉这个判断 - 注意:JDK 7+ 推荐改用
Files.exists(Paths.get(...)),它支持LinkOption.NOFOLLOW_LINKS,避免符号链接陷阱
mkdir() 和 mkdirs() 差在哪?建多级目录时必踩的坑
mkdir() 只创建最后一级目录,父目录不存在就静默失败;mkdirs() 才递归建全路径。但很多人没意识到:即使 mkdirs() 返回 true,也不能保证目录真能用。
- 返回
false不一定代表失败——可能是权限不足、磁盘满、父目录被其他进程锁定 - Windows 下路径含
:或<等非法字符时,mkdirs()也返回false,但不抛异常,需手动校验路径合法性 - 建议后续立刻调用
exists()+isDirectory()双重确认,尤其在容器或 CI 环境中
delete() 为什么删不掉文件?三个常见拦截点
File.delete() 返回 false 是常态,不是 bug。它不抛异常,只靠返回值说话,容易被忽略。
- 文件正被 JVM 或其他进程打开(比如
FileInputStream没 close,或 IDE 正在索引) - Windows 下文件被标记为只读(
setReadOnly()设置过),需先setWritable(true) - 目标是目录且非空:
delete()不会递归删除,必须自己遍历子项先清空
替代方案:JDK 7+ 用 Files.delete() 或 Files.deleteIfExists(),它们会明确抛出 IOException,错误信息更具体。
立即学习“Java免费学习笔记(深入)”;
File 类已过时?什么场景还必须用它
不是所有地方都能直接上 Path 和 Files。比如某些老框架(如早期 Spring Resource、Log4j 1.x)的 API 仍强制接收 File 对象;还有 JNI 调用、部分系统命令行工具封装也需要原始 File 实例。
- 不要为了“新”而强行转换:用
file.toPath()得到Path后,若还要传回旧接口,再转回来就行 -
File.list()返回String[],不带路径信息;而Files.list()返回流式Stream<path></path>,更安全但需处理ClosedChannelException - 跨平台路径拼接别用
+字符串拼接,始终用File.separator或Paths.get("a", "b", "c")
真正麻烦的从来不是 API 本身,而是没意识到 File 对象不感知文件系统实时状态 —— 它只是路径快照。下次看到 exists() 返回 false,先看看是不是别人刚删了它,而不是代码写错了。


















