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

我正在枚举目录中的所有文件,以便稍后处理它们。 我想排除隐藏和系统文件。

这是我到目前为止:

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

但是,如果我查看结果,我仍然会隐藏并包含系统文件:

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

我发现这个问题与杰罗姆有类似的例子,但我甚至无法编译。

我究竟做错了什么?

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

由于FileAttributes值是标志,因此它们在位级别上是分离的,因此您可以正确地组合它们。 因此, FileAttributes.Hidden & FileAttributes.System将始终为0 。 所以你基本上检查以下内容:

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

这将永远是真的,因为您使用& 0部分删除任何值。

您要检查的是文件是否既没有这些标志,换句话说,如果没有两个组合的公共标志:

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

你也可以使用Enum.HasFlag使这个更容易理解:

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

您可以使用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); 

您的原始代码尝试在没有公共位的标志之间执行按位AND,因此它返回0.因此,带Attributes的按位AND也返回0。

要检查的掩码是System Hidden,即FileAttributes.Hidden | FileAttributes.System FileAttributes.Hidden | FileAttributes.System 。 事先计算它只会使代码更清晰

您可以使用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);