file.exists()仅表示路径存在,不区分文件/目录且不校验权限;需配合isFile()、canWrite()、isDirectory()等方法验证类型与权限,mkdirs()才递归创建目录,JDK7+推荐用Files.exists()替代。

file.exists() 返回 true 不代表你能用它
它只告诉你路径“存在”,但不区分是文件、目录,也不校验权限。比如 new File("logs").exists() 返回 true,但它可能是个空目录——你后续想 new FileInputStream("logs") 就会直接抛 FileNotFoundException。
常见误判场景:
- 把目录当文件读:没加
isFile()校验,exists()为true就开流,崩 - 想写入却无写权限:
exists()成功,canWrite()却是false,写操作失败 - 符号链接指向失效路径:
exists()可能返回false(取决于系统是否跟随链接)
创建目录必须分清 mkdir() 和 mkdirs()
mkdir() 只建最后一级,上级目录不存在就静默失败;mkdirs() 才会递归建全路径。别指望 mkdir() 自动补父目录。
正确做法:
- 要建
"a/b/c"这种嵌套路径,必须用new File("a/b/c").mkdirs() - 如果只调
mkdir(),且"a"或"a/b"不存在,返回false,且不报错,容易被忽略 - 注意返回值:
mkdirs()成功才返回true,失败(如磁盘满、权限不足)也返回false,需检查
检查 + 创建组合操作必须加 exists() + isDirectory() 双重判断
仅靠 exists() 无法确认目标是不是你想要的目录类型。例如你期望一个日志目录 "./logs",但同名文件已存在,exists() 是 true,mkdirs() 却不会覆盖,还会失败。
安全写法示例:
File dir = new File("./logs");
if (!dir.exists()) {
if (!dir.mkdirs()) {
throw new RuntimeException("无法创建日志目录:" + dir.getAbsolutePath());
}
} else if (!dir.isDirectory()) {
throw new RuntimeException("路径存在但不是目录:" + dir.getAbsolutePath());
}
关键点:
- 先
exists(),再isDirectory(),顺序不能反(对不存在路径调isDirectory()永远返回false) - 不要省略
mkdirs()的返回值判断——它不抛异常,只靠布尔值反馈成败 - 路径分隔符建议用
File.separator或统一用正斜杠"/",避免 Windows 下反斜杠转义问题
JDK 7+ 应优先用 Files.exists() 替代 file.exists()
Files.exists(Paths.get("path")) 更可靠:支持传 LinkOption.NOFOLLOW_LINKS,避免符号链接干扰;语义更明确;且和 Files.createDirectories() 配套,行为一致。
对比差异:
-
file.exists()对不可达网络路径或权限受限路径可能阻塞或返回false(无明确原因) -
Files.exists()在多数情况下响应更快,错误更易诊断 - 若必须兼容旧 JDK,至少补上
canRead()/canWrite()校验,别只信exists()
真正容易被忽略的是:哪怕 exists() 和 isDirectory() 都通过了,listFiles() 仍可能返回 null(权限不足时),这时得靠 canRead() 提前兜底。

















