【问题标题】:How to check if a file/directory is a protected OS file?如何检查文件/目录是否是受保护的操作系统文件?
【发布时间】:2016-08-01 19:29:40
【问题描述】:

我正在开发一个项目,该项目在一定程度上显示了 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() is'也更好)。

然而, file.isHidden() 返回 false

canWrite()/canRead()/canExecute() 返回真

getPath() 与 getAbsolutePath() 和 getCanonicalPath() 返回相同

createNewFile() 对所有内容都返回 false,即使是我知道的目录也可以。另外,即使可行,这也是我非常想避免的解决方案。

是否有一些我只是不知道的方法或实现来帮助我查看该目录是否可以访问而无需解析其所有内容?

(我正在运行 Windows 7 Professional,我正在使用 Eclipse Mars 4.5.2,并且 File 的所有实例都是 java.io.File)。

【问题讨论】:

  • 如果您想进行准确的文件系统对象操作,请忘记File 并改用 JSR 203。更多详情here.
  • 我有 3500 行。这有点晚了。不过谢谢,我一定会在我的下一个项目中检查一下。
  • 问题是,你必须这样做。 File 做不到。期间...
  • 这是我很长一段时间以来听到的最具毁灭性的消息
  • JSR 203 可以,这就是为什么我包含上面的链接(我已经写了)。我将在下面写一个详细的答案,但无论如何大部分都会重复这个链接。此外,您必须定义“受保护”:用户不能读/写?操作系统是否实施了内置限制?等等等等。

标签: java file


【解决方案1】:

您遇到的问题是您正在处理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 实例还允许您使用FileSystem#getPath 访问Path

结合这个,你会发现这两者是等价的:

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

关于异常:File 处理得很差。举两个例子:

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

JSR 203 没有这些缺点,而且做得更多。让我们采用两种等效的方法:

这些方法和其他方法在行为上有根本区别:如果发生故障,它们会抛出异常。

此外,您可以区分这是什么异常:

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

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

【讨论】:

  • 只是为了确定,使用 Path 与使用 File 对象“相同”但更好?
  • @MeikVtune 不完全;虽然来自 File 的元数据在 File 本身内,但使用新 API,您需要查询 API 的其他部分; Files 实用程序类是它的主要入口点。请注意,这在 99% 以上的情况下就足够了,但一些非常具体的用途可能需要您同时使用 API 的其他部分
  • here 链接已失效。您是否有替换链接,或者您可以在答案中添加一点 sn-p 如何使用它?
【解决方案2】:

我在使用C://users/myuser/cookies 之类的路径时遇到了同样的问题。

我已经使用过 JSR203,所以上面的答案对我没有帮助。 在我的例子中,这些文件的重要属性是隐藏的。

我最终使用了 FileSystemview,它根据需要排除了这些文件。

File[] files = FileSystemView.getFileSystemView().getFiles(new File(strHomeDirectory), !showHidden);

【讨论】:

    猜你喜欢
    • 2012-08-16
    • 1970-01-01
    • 2018-05-13
    • 2013-01-04
    • 2023-03-03
    • 1970-01-01
    • 2015-08-24
    • 2013-02-05
    • 1970-01-01
    相关资源
    最近更新 更多