应优先用 files.exists() 和 files.isreadable() 主动检测路径存在性与读权限,而非依赖 exists() 或捕获 filenotfoundexception;file.canread()/canwrite() 仅作兼容补充,且结果仅为瞬时快照。

检查文件是否存在和读写权限,不能只靠 exists() 或捕获 FileNotFoundException 来判断。因为 exists() 返回 true 只说明路径存在(可能是目录),不代表能读;而 FileNotFoundException 既可能因路径不存在触发,也可能因权限不足、符号链接失效甚至目录被误当文件打开而抛出——它不专指“文件没找到”。
先用 Files.exists() 和 Files.isReadable() 主动探测
这是 JDK7+ 推荐的标准做法,逻辑清晰、跨平台稳定,不依赖异常分支:
-
Files.exists(path):确认路径是否真实可达。返回
false表示父目录链中断、路径根本不存在,或当前进程连路径所在目录都进不去 -
Files.isReadable(path):在
exists()为true的前提下,检查是否有读取权限。若为false,大概率是权限问题(如 Linux 缺少r位、Windows ACL 拒绝) - 如需区分符号链接本身与目标,加
LinkOption.NOFOLLOW_LINKS参数
用 File.canRead() / canWrite() 快速试探(兼容老项目)
适用于仍用 java.io.File 的场景,注意它的行为特点:
-
file.canRead() 返回
true 需同时满足两个条件:文件存在 + 当前 JVM 进程有读权限;任一不满足就返回 <code>false - file.canWrite() 同理,但对目录而言,“可写”意味着能创建/删除子项,不是改目录内容
- 这些方法不抛异常,但结果只是“此刻的快照”,不保证后续操作一定成功(比如权限被其他进程瞬间修改)
别把 exists() 当权限检查用
File.exists() 仅回答“路径是否存在”,它不管你是想读、写还是执行:
- 对一个只读文件,
exists()返回true,但canWrite()是false - 对一个空目录,
exists()和canRead()都可能为true,但它显然不是文件 - 真正要读文件时,应组合判断:
exists() && isFile() && canRead()
异常里找线索?谨慎对待
如果必须从 FileNotFoundException 中推测原因,可看两点,但不能用于正式逻辑分支:
-
getMessage() 里偶尔含关键词,如
"Permission denied"或"No such file or directory",但字符串可能被本地化或截断 -
getCause() 在部分 JVM 中可能包装系统级异常(如
UnixException),其errorCode有参考价值(如EACCESvsENOENT),但非标准,不可移植
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











