我正在编写 Java 6 应用程序,我必须检查文件是否可读。但是,在 Windows 上
canRead()
始终返回 true
。所以我认为,唯一的解决方案可能是一些基于 WINAPI 并用 JNA/JNI 编写的本机解决方案。
但是,还有另一个问题,因为在 WINAPI 中很难找到一个简单的函数来返回有关文件访问的信息。我找到了
GetNamedSecurityInfo
或 GetSecurityInfo
,但我不是高级 WINAPI 程序员,它们与 JNA/JNI 的连接对我来说太复杂了。有什么想法如何处理这个问题吗?
Java 7 引入了
Files.isReadable
静态方法,它接受一个文件 Path
,如果文件存在且可读则返回 true,否则返回 false。
测试文件是否可读。该方法检查文件是否存在 并且该 Java 虚拟机具有适当的权限 允许它打开文件进行读取。根据实施情况,这 方法可能需要读取文件权限、访问控制列表或 其他文件属性,以便检查对文件的有效访问。 因此,此方法相对于其他文件可能不是原子的 系统操作。
注意,该方法的结果立即过时,有 不保证随后尝试打开文件进行读取将 成功(甚至它将访问同一个文件)。应小心 在安全敏感应用程序中使用此方法时。
示例:
File file = new File("/path/to/file");
Files.isReadable(file.toPath()); // true if `/path/to/file` is readable
尝试使用以下代码
public boolean checkFileCanRead(File file){
try {
FileReader fileReader = new FileReader(file.getAbsolutePath());
fileReader.read();
fileReader.close();
} catch (Exception e) {
LOGGER.debug("Exception when checking if file could be read with message:"+e.getMessage(), e);
return false;
}
return true;
}
您可以通过这种方式更严格地使用 FilePermission 和 AccessController :
FilePermission fp = new FilePermission("file.txt", "read");
AccessController.checkPermission(fp);
如果允许请求的访问,则 checkPermission 会安静地返回。如果 被拒绝,抛出 AccessControlException。
如果您要阅读它,您只需要知道它是否可读即可。所以,当你需要的时候,试着去读它,如果不能的话,就处理它。测试任何资源可用性的最佳方法就是尝试使用它并处理出现的异常或错误。不要试图预测未来。
在实际使用资源之前很久检查资源的可访问性(在本例中是文件的可读性)是完全合理的。
想象一个服务器应用程序将使用一个子组件,该子组件将在某些情况下在一段时间后读取特定文件。在服务器启动时检查文件的可读性非常有用,如果不可读则发出警告。然后有人可以在情况实际导致子组件尝试读取该文件之前修复该情况(使文件可读,任何东西)。
当然,这种预先检查并不能替代子组件中正确的异常处理(文件很可能在开始时可读,但后来变得不可读)。
所以我认为关于预检查的问题是完全有效的。
关于检查资源的方法,尽量与实际使用情况类似。如果稍后会读取该文件,请尝试读取它!
对于 Files.isReadable(...):不能保证 Files.isReadable(...) 下的文件系统提供程序没有错误。它可以返回true,然后如果文件被实际读取则抛出异常。
当然,如果您正在编写文件管理器应用程序,则使用 Files.isReadable(...),但我想情况并非如此。