【问题标题】:How to use Directory.EnumerateFiles excluding hidden and system files如何使用 Directory.EnumerateFiles 不包括隐藏和系统文件
【发布时间】:2016-01-05 11:51:56
【问题描述】:

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

这是我目前所拥有的:

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

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

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

我发现 this question 有一个来自 Jerome 的类似示例,但我什至无法编译。

我做错了什么?

【问题讨论】:

  • FileAttributes.Hidden &amp; FileAttributes.System 始终等于 0。
  • 哦,我没有意识到这一点。我尝试了(new FileInfo(f).Attributes &amp; FileAttributes.Hidden) != FileAttributes.Hidden),它有效,但我也很难弄清楚如何在其中包含系统文件。
  • 此外,如果您要创建一个新的 FileInfo,请从 DirectoryInfo 开始,这样您就可以从一开始就获得 FileInfo 对象。至于过滤器,试试fi.Attributes &amp; (FileAttributes.Hidden | FileAttributes.System)) == 0。首先创建你想要的掩码FileAttributes.Hidden | FileAttributes.System,然后然后进行按位与。文件夹路径也可通过FileInfo.DirectoryName

标签: c# ienumerable fileinfo


【解决方案1】:
.Where(f => (new FileInfo(f).Attributes & FileAttributes.Hidden & FileAttributes.System) == 0)

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

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

这始终是正确的,因为您正在使用 &amp; 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))

【讨论】:

  • 绝对精彩,也感谢您的解释。将在 4 分钟内接受 ;-)
【解决方案2】:

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

您的原始代码尝试在没有公共位的标志之间进行按位与,因此它返回 0。结果,与Attributes 的按位与也返回 0。

您要检查的掩码是系统隐藏,即FileAttributes.Hidden | FileAttributes.System。提前计算这个值只会让代码更简洁

【讨论】:

  • 在 Where 子句中,按位 & 表达式需要用括号括起来,因为 == 的优先级高于 &,即.Where(fi =&gt; (fi.Attributes &amp; mask) == 0)
【解决方案3】:

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

【讨论】:

    猜你喜欢
    • 2011-10-12
    • 2018-05-30
    • 1970-01-01
    • 2023-03-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-07-30
    相关资源
    最近更新 更多