简体   繁体   English

如何使用Directory.EnumerateFiles,不包括隐藏文件和系统文件

[英]How to use Directory.EnumerateFiles excluding hidden and system files

I'm enumerating all files in a directory so that I can process them later. 我正在枚举目录中的所有文件,以便稍后处理它们。 I want to exclude hidden and system files. 我想排除隐藏和系统文件。

This is what I have so far: 这是我到目前为止:

IEnumerable<IGrouping<string, string>> files;

files = Directory.EnumerateFiles(sourcePath, "*", SearchOption.AllDirectories)
       .Where(f => (new FileInfo(f).Attributes & FileAttributes.Hidden & FileAttributes.System) == 0)
       .GroupBy(Path.GetDirectoryName);

However if I look at the results I am still getting hidden and system files included: 但是,如果我查看结果,我仍然会隐藏并包含系统文件:

foreach (var folder in files)
{
    foreach (var file in folder)
    {
        // value for file here still shows hidden/system file paths
    }
}

I found this question which has a similar example from Jerome but I couldn't even get that to compile. 我发现这个问题与杰罗姆有类似的例子,但我甚至无法编译。

What am I doing wrong? 我究竟做错了什么?

.Where(f => (new FileInfo(f).Attributes & FileAttributes.Hidden & FileAttributes.System) == 0)

Since FileAttributes values are flags, they are disjunctive on the bit level, so you can combine them properly. 由于FileAttributes值是标志,因此它们在位级别上是分离的,因此您可以正确地组合它们。 As such, FileAttributes.Hidden & FileAttributes.System will always be 0 . 因此, FileAttributes.Hidden & FileAttributes.System将始终为0 So you're essentially checking for the following: 所以你基本上检查以下内容:

(new FileInfo(f).Attributes & 0) == 0

And that will always be true since you are removing any value with the & 0 part. 这将永远是真实的,因为您使用& 0部分删除任何值。

What you want to check is whether the file has neither of those flags, or in other words, if there are no common flags with the combination of both: 您要检查的是文件是否既没有这些标志,换句话说,如果没有两个组合的公共标志:

.Where(f => (new FileInfo(f).Attributes & (FileAttributes.Hidden | FileAttributes.System)) == 0)

You can also use Enum.HasFlag to make this a bit better understandable: 你也可以使用Enum.HasFlag使这个更容易理解:

.Where(f => !new FileInfo(f).Attributes.HasFlag(FileAttributes.Hidden | FileAttributes.System))

You can simplify your code a lot by using DirectoryInfo and FileInfo, eg: 您可以使用DirectoryInfo和FileInfo大量简化代码,例如:

var mask= FileAttributes.Hidden | FileAttributes.System;

var di=new DirectoryInfo(sourcePath);
var files=di.EnumerateFiles("*", SearchOption.AllDirectories)
            .Where(fi=>(fi.Attributes & mask) == 0)
            .GroupBy(fi=>fi.DirectoryName);

Your original code tried to do a bitwise AND between flags that had no common bits, so it returned 0. As a result, the bitwise AND with Attributes also returned 0. 您的原始代码尝试在没有公共位的标志之间执行按位AND,因此返回0.因此,带Attributes的按位AND也返回0。

The mask you want to check against is System or Hidden ie FileAttributes.Hidden | FileAttributes.System 要检查的掩码是System Hidden,即FileAttributes.Hidden | FileAttributes.System FileAttributes.Hidden | FileAttributes.System . FileAttributes.Hidden | FileAttributes.System Calculating this in advance simply makes for somewhat cleaner code 事先计算它只会使代码更清晰

You can use FileSystemInfo.Attributes.HasFlag : 您可以使用FileSystemInfo.Attributes.HasFlag

DirectoryInfo dir = new DirectoryInfo( sourcePath );
var files = dir.EnumerateFiles("*", SearchOption.AllDirectories)
    .Where(f => !f.Attributes.HasFlag(FileAttributes.Hidden) && !f.Attributes.HasFlag(FileAttributes.System))
    .GroupBy(f => f.DirectoryName);

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

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