我正在做一个项目,该项目部分地显示JTable目录中的所有文件,包括子目录。用户可以双击子目录以使用该新目录的内容更新表。但是,我遇到了一个问题。
我的文件列表是用 file.listFiles(( 生成的,它提取了所有内容:隐藏文件、锁定文件、操作系统文件、整个工具包和 caboodle,我无法访问所有这些文件。例如,我没有读取/写入"C:\Users\user\Cookies\"或"C:\ProgramData\ApplicationData\"的权限。不过没关系,这不是关于访问这些的问题。相反,我不希望程序显示无法打开的目录。但是,我无权访问的目录和我做的目录的行为几乎完全相同,这使得很难过滤掉它们。
我发现的唯一行为差异是,如果我在锁定的目录上调用 listFiles((,它会返回 null。这是我用作过滤器的代码块:
for(File file : folder.listFiles())
if(!(file.isDirectory() && file.listFiles() == null))
strings.add(file.getName());
其中"文件夹"是我正在查看的目录,"字符串"是该目录中文件名称的列表。这个想法是,只有当文件是我被允许编辑的文件或目录时,文件才会加载到列表中。过滤方面是有效的,但是有一些目录包含数百个子目录,每个子目录包含数百个文件,并且由于listFiles((是O(n(,这不是一个可行的解决方案(list((也没有更好(。
然而file.isHidden(( 返回 false
canWrite((/canRead((/canExecute(( 返回 true
getPath(( 返回与 getAbsolutePath(( 和 getCanonicalPath(( 相同的值
createNewFile(( 对所有内容都返回 false,即使我知道的目录也可以。另外,即使有效,这也是我真正想避免的解决方案。
是否有一些我不知道的方法或实现可以帮助我查看是否可以访问此目录而无需解析其所有内容?
(我运行的是Windows 7 Professional,我使用的是Eclipse Mars 4.5.2,文件的所有实例都是java.io.File(。
您遇到的问题是您正在处理File
.从各方面来看,在 2016 年,事实上,自 2011 年(Java 7 发布时(以来,它已被 JSR 203 取代。
现在,什么是JSR 203?它是一个全新的 API,用于处理任何文件系统和文件系统对象;它扩展了"文件系统"的定义,以包括您在本地机器(JDK 所谓的"默认文件系统"(和您可能使用的其他文件系统上找到的内容。
有关如何使用它的示例页面:此处
此 API 的众多优点之一是它授予对以前无法访问的元数据的访问权限;例如,您在注释中特别提到了您想知道 Windows 认为哪些文件是"系统文件"的情况。
这是你可以做到的:
// get the path
final Path path = Paths.get(...);
// get the attributes
final DosAttributes attrs = Files.readAttributes(path, DosFileAttributes.class);
// Is this file a "system file"?
final boolean isSystem = attrs.isSystem();
现在,什么是Paths.get()
?如前所述,API 允许您一次访问多个文件系统;一个名为 FileSystems
的类允许访问 JDK 可见的所有文件系统(包括创建新文件系统(,而始终存在的默认文件系统由 FileSystems.getDefault()
提供
FileSystem
实例还允许您使用 FileSystem#getPath
访问Path
。
结合这一点,你会得到这两者是等效的:
Paths.get(a, b, ...)
FileSystems.getDefault().getPath(a, b, ...)
关于例外:File
处理它们非常糟糕。仅举两个例子:
- 如果无法创建文件,
File#createNewFile
将返回 false; - 如果由于某种原因无法读取
File
对象所指向的目录的内容,File#listFiles
将返回 null。
JSR 203 没有这些缺点,甚至更多。让我们采用两种等效的方法:
-
File#createNewFile
变得Files#createFile
; -
File#listFiles
成为Files#newDirectoryStream
(或衍生物;参见javadoc(或(自Java 8起(Files#list
。
这些方法和其他方法在行为上有着根本的不同:如果发生故障,它们将引发异常。
更重要的是,您可以区分这是什么例外:
- 如果是
FileSystemException
或衍生物,则错误在文件系统级别(例如,"拒绝访问"是一个AccessDeniedException
(; - 如果IS是一个
IOException
,那么问题更根本。
这个答案不能包含JSR 203的每一个用例;这个API是巨大的,非常完整的,虽然不是没有缺陷,但它在任何情况下都比File
所提供的要好得多。
C://users/myuser/cookies
这样的路径上遇到了同样的问题。
我已经用过JSR203了,所以上面的答案对我没有帮助。就我而言,这些文件的重要属性是隐藏的。
我最终使用了文件系统视图,它根据需要排除了这些文件。
File[] files = FileSystemView.getFileSystemView().getFiles(new File(strHomeDirectory), !showHidden);