我正在一个项目中,该项目部分地显示JTable目录中的所有文件,包括子目录。用户可以双击子目录以使用该新目录的内容更新表。但是,我遇到了一个问题。

我的文件列表是使用file.listFiles()生成的,它可以提取所有内容:隐藏文件,锁定文件,OS文件,整个工具包和cabo​​odle,但我无法访问所有文件。例如,我无权在“ 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,并且File的所有实例都是java.io.File)。

最佳答案

您遇到的问题是您正在处理File。从所有人的角度来看,从2016年开始,实际上是从2011年(Java 7发布时)开始,它已被JSR 203取代。

现在,什么是JSR 203?它是一种全新的API,可以处理任何文件系统和文件系统对象。它扩展了“文件系统”的定义,以包括您在本地计算机上找到的文件(JDK所谓的“默认文件系统”)和其他可能使用的文件系统。

有关如何使用它的示例页面:here

该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实例还使您可以使用Path访问FileSystem#getPath

结合这一点,您会发现这两个是等效的:

Paths.get(a, b, ...)
FileSystems.getDefault().getPath(a, b, ...)




关于异常:File对异常的处理非常差。仅举两个例子:


如果无法创建文件,File#createNewFile将返回false;否则,将返回false。
如果File#listFiles对象指向的目录的内容由于某种原因而无法读取,则File将返回null。


JSR 203没有这些缺点,甚至还有更多缺点。让我们采用两种等效的方法:


File#createNewFile变为Files#createFile;
File#listFiles成为Files#newDirectoryStream(或派生;请参阅javadoc)或(自Java 8起)Files#list之一。


这些方法和其他方法在行为上有根本的区别:如果失败,它们将引发异常。

而且,您可以区分这是什么异常:


如果它是FileSystemException或派生类,则错误发生在文件系统级别(例如,“拒绝访问”是AccessDeniedException);
如果是IOException,则问题更为根本。




这个答案不能包含JSR 203的每一个用例;这个API庞大,非常完整,尽管并非没有缺陷,但无论如何都比File所提供的要好得多。

07-24 18:56
查看更多