简体   繁体   English

如何检查文件/目录是否是受保护的操作系统文件?

[英]How to check if a file/directory is a protected OS file?

I'm working on a project which, in part, displays all the files in a directory in a JTable, including sub-directories.我正在处理一个项目,该项目部分显示 JTable 目录中的所有文件,包括子目录。 Users can double-click the sub-directories to update the table with that new directory's content.用户可以双击子目录以使用该新目录的内容更新表。 However, I've run into a problem.但是,我遇到了一个问题。

My lists of files are generated with file.listFiles(), which pulls up everything: hidden files, locked files, OS files, the whole kit and caboodle, and I don't have access to all of them.我的文件列表是使用 file.listFiles() 生成的,它可以提取所有内容:隐藏文件、锁定文件、操作系统文件、整个套件和 caboodle,但我无法访问所有这些文件。 For example, I don't have permission to read/write in "C:\\Users\\user\\Cookies\\" or "C:\\ProgramData\\ApplicationData\\".例如,我没有在“C:\\Users\\user\\Cookies\\”或“C:\\ProgramData\\ApplicationData\\”中读/写的权限。 That's ok though, this isn't a question about getting access to these.不过没关系,这不是关于访问这些的问题。 Instead, I don't want the program to display a directory it can't open.相反,我不希望程序显示它无法打开的目录。 However, the directories I don't have access to and the directories I do are behaving almost exactly the same, which is making it very difficult to filter them out.但是,我无权访问的目录和我访问的目录的行为几乎完全相同,这使得过滤它们变得非常困难。

The only difference in behavior I've found is if I call listFiles() on a locked directory, it returns null.我发现的唯一行为差异是,如果我在锁定目录上调用 listFiles(),它会返回 null。 Here's the block of code I'm using as a filter:这是我用作过滤器的代码块:

for(File file : folder.listFiles())
    if(!(file.isDirectory() && file.listFiles() == null))
        strings.add(file.getName());

Where 'folder' is the directory I'm looking inside and 'strings' is a list of names of the files in that directory.其中“文件夹”是我正在查看的目录,“字符串”是该目录中文件的名称列表。 The idea is a file only gets loaded into the list if it's a file or directory I'm allowed to edit.这个想法是一个文件只有在它是我被允许编辑的文件或目录时才会被加载到列表中。 The filtering aspect works, but there are some directories which contain hundreds of sub-directories, each of which contains hundreds more files, and since listFiles() is O(n), this isn't a feasible solution (list() isn't any better either).过滤方面有效,但有一些目录包含数百个子目录,每个子目录包含数百个文件,并且由于 listFiles() 是 O(n),这不是一个可行的解决方案(list() 不是或者更好)。

However, file.isHidden() returns false但是,file.isHidden() 返回 false

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

getPath() returns the same as getAbsolutePath() and getCanonicalPath() getPath() 返回与 getAbsolutePath() 和 getCanonicalPath() 相同

createNewFile() returns false for everything, even directories I know are ok. createNewFile() 对所有内容都返回 false,即使我知道的目录也可以。 Plus, that's a solution I'd really like to avoid even if that worked.另外,这是一个我真的很想避免的解决方案,即使它有效。

Is there some method or implementation I just don't know to help me see if this directory is accessible without needing to parse through all of its contents?是否有一些我不知道的方法或实现可以帮助我查看该目录是否可以访问而无需解析其所有内容?

(I'm running Windows 7 Professional and I'm using Eclipse Mars 4.5.2, and all instances of File are java.io.File). (我运行的是 Windows 7 Professional,我使用的是 Eclipse Mars 4.5.2,并且 File 的所有实例都是 java.io.File)。

The problem you have is that you are dealing with File .您遇到的问题是您正在处理File By all accounts, in 2016, and, in fact, since 2011 (when Java 7 came out), it has been superseded by JSR 203.从各方面来看,在 2016 年,事实上,自 2011 年(Java 7 出现时)以来,它已被 JSR 203 取代。

Now, what is JSR 203?现在,什么是 JSR 203? It is a totally new API to deal with anything file systems and file system objects;它是一个全新的 API,可以处理任何文件系统和文件系统对象; and it extend the definition of a "file system" to include what you find on your local machine (the so called "default filesystem" by the JDK) and other file systems which you may use.并且它扩展了“文件系统”的定义,以包括您在本地机器上找到的内容(JDK 所谓的“默认文件系统”)和您可能使用的其他文件系统。

Sample page on how to use it: here关于如何使用它的示例页面:这里

Among the many advantages of this API is that it grants access to metadata which you could not access before;这个 API 的众多优点之一是它可以访问您以前无法访问的元数据; for instance, you specifically mention the case, in a comment, that you want to know which files Windows considers as "system files".例如,您在评论中特别提到了您想知道 Windows 将哪些文件视为“系统文件”的情况。

This is how you can do it:你可以这样做:

// 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();

Now, what is Paths.get() ?现在,什么是Paths.get() As mentioned previously, the API gives you access to more than one filesystem at a time;如前所述,API 允许您一次访问多个文件系统; a class called FileSystems gives access to all file systems visible by the JDK (including creating new filesystems), and the default file system, which always exists, is given by FileSystems.getDefault() .一个名为FileSystems的类可以访问 JDK 可见的所有文件系统(包括创建新文件系统),并且始终存在的默认文件系统由FileSystems.getDefault()给出。

A FileSystem instance also gives you access to a Path using FileSystem#getPath . FileSystem实例还允许您使用FileSystem#getPath访问Path

Combine this and you get that those two are equivalent:结合这个,你会发现这两个是等价的:

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

About exceptions: File handles them very poorly.关于异常: File处理它们非常糟糕。 Just two examples:举两个例子:

  • File#createNewFile will return false if the file cannot be created;如果无法创建File#createNewFile将返回 false;
  • File#listFiles will return null if the contents of the directory pointed by the File object cannot be read for whatever reason.如果由于某种原因无法读取File对象指向的目录的内容,则File#listFiles将返回 null。

JSR 203 has none of these drawbacks, and does even more. JSR 203 没有这些缺点,甚至更多。 Let us take the two equivalent methods:让我们采用两种等效的方法:

These methods, and others, have a fundamental difference in behaviour: in the event of a failure, they will throw an exception.这些方法和其他方法在行为上有着根本的区别:在失败的情况下,它们会抛出异常。

And what is more, you can differentiate what exception this is:更重要的是,您可以区分这是什么异常:

  • if it is a FileSystemException or derivative, the error is at the filesystem level (for instance, "access denied" is an AccessDeniedException );如果是FileSystemException或派生类,则错误在文件系统级别(例如,“访问被拒绝”是AccessDeniedException );
  • if is is an IOException , then the problem is more fundamental.如果 is 是一个IOException ,那么问题就更基本了。

This answer cannot contain each and every use case of JSR 203;这个答案不能包含 JSR 203 的每一个用例; this API is vast, very complete, although not without flaws, but it is infinitely better than what File has to offer in any case.这个 API 非常庞大,非常完整,虽然并非没有缺陷,但无论如何它都比File提供的要好得多。

I faced the very same problem with paths like C://users/myuser/cookies .我在使用C://users/myuser/cookies类的路径时遇到了同样的问题。

I already used JSR203, so the above answer kind of didn't help me.我已经使用过 JSR203,所以上面的答案对我没有帮助。 In my case the important attribute of those files was the hidden one.就我而言,这些文件的重要属性是隐藏的。

I ended up using the FileSystemview, which excluded those files as I wanted.我最终使用了 FileSystemview,它根据需要排除了这些文件。

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM