C#-获取文件列表(不包括隐藏文件)


67

Directory.GetFiles()返回所有文件,即使标记为隐藏的文件也是如此。有没有办法获取排除隐藏文件的文件列表?

Answers:


104

这应该为您工作:

DirectoryInfo directory = new DirectoryInfo(@"C:\temp");
FileInfo[] files = directory.GetFiles();

var filtered = files.Where(f => !f.Attributes.HasFlag(FileAttributes.Hidden));

foreach (var f in filtered)
{
    Debug.WriteLine(f);
}

据我了解,c#4.0应该使此过程变得更快,更容易;-)
Dested 2010年

13
您可以单行执行此操作,而无需SELECT var files = new DirectoryInfo(@“ C:\”)。GetFiles()。Where(x =>(x.Attributes&FileAttributes.Hidden)== 0);
Adriaan Stander 2010年

5
甚至只是使用目录类(将@astanders解决方案减少8个字符)var files = Directory.GetFiles(@“ c:\”)。Where(x =>(x.Attributes&FileAttributes.Hidden)== 0);
µBio 2010年

5
Directory.GetFiles返回一个字符串数组,因此您的代码高尔夫解决方案无法正常工作。
奥斯丁·萨洛宁

1
@AustinSalonen是正确的,您不能对Directory.GetFiles使用上述“代码高尔夫”解决方案,但可以使用以下讨厌的代码:Directory.GetFiles(@“ C:\”)。Where(x =>(新的FileInfo(x).Attributes和FileAttributes.Hidden)== 0)。我并不是说你应该,但是你可以。
bopapa_1979

14
// check whether a file is hidden
bool isHidden = ((File.GetAttributes(filePath) & FileAttributes.Hidden) == FileAttributes.Hidden);

这在linq不可用的地方很有用
JDandChips 2012年

2
简单的解决方案可能很优雅-我喜欢人们展示解决方案而不炫耀Linq
Kairan 2013年

1
或等效地,如果您愿意降低性能,则File.GetAttributes(filePath).HasFlag(FileAttributes.Hidden)。
Warty 2014年

对于性能而言,这不是最佳解决方案。我在网络设备上尝试过它,它比接受的答案慢得多
Vortex852456

8

使用.NET 4.0和Directory.EnumerateDirectories,可以使用以下结构:

var hiddenFilesQuery = from file in Directory.EnumerateDirectories(@"c:\temp")
                       let info = new FileInfo(file)
                       where (info.Attributes & FileAttributes.Hidden) == 0
                       select file;

这与其他答案基本相同,除了Directory.EnumerateDirectories有点懒。但是,如果您枚举所有内容,这不是很有用。

(让这里有一个查询,但更可读)。


2

如果使用,请使用:

var filtered = files.Select(f => f) .Where(f => (f.Attributes & FileAttributes.Hidden) == 0);

这只会找到隐藏文件,因此您可以使用:

var filtered = files.Select(f => f) .Where(f => (f.Attributes & FileAttributes.Hidden) == FileAttributes.Hidden);

这只是读取隐藏的文件


2

一行代码:

FileInfo[] tmpFiles = tempDir.GetFiles().Where(file => 
            (file.Attributes & FileAttributes.Hidden) == 0).ToArray();

1

如果您使用的是SearchOption.TopDirectoryOnly,那么相对来说比较简单,但是如果要使用SearchOption.AllDirectories递归列出所有文件,则变得更加复杂。如果可以,请获取GetFiles,然后以只读方式过滤掉,但不幸的是,它不适用于标记为隐藏的目录。该文件夹下的文件也将列出,但与目录不同,它们不会被隐藏。

您也可以使用GetDirectories,但是再次-您不能使用SearchOption.AllDirectories递归列出所有内容,因为它还会列出位于隐藏文件夹下的文件夹,但是这些文件夹未启用hidden属性。

至少对于Tortoise svn .svn隐藏文件夹就是这种情况。它包含许多未隐藏的文件夹,但是.svn被隐藏。最后,我编写了如下函数:

    SearchOption sopt = SearchOption.AllDirectories;
    List<String> listFiles = new List<string>();
    List<DirectoryInfo> dirs2scan = new List<DirectoryInfo>();

    dirs2scan.Add(new DirectoryInfo(fromPath) );

    for( ; dirs2scan.Count != 0; )
    {
        int scanIndex = dirs2scan.Count - 1;        // Try to preserve somehow alphabetic order which GetFiles returns 
                                                    // by scanning though last directory.
        FileInfo[] filesInfo = dirs2scan[scanIndex].GetFiles(pattern, SearchOption.TopDirectoryOnly);

        foreach (FileInfo fi in filesInfo)
        {
            if (bNoHidden && fi.Attributes.HasFlag(FileAttributes.Hidden))
                continue;

            listFiles.Add(fi.FullName);
        }

        if( sopt != SearchOption.AllDirectories )
            break;

        foreach (DirectoryInfo dir in dirs2scan[scanIndex].GetDirectories("*", SearchOption.TopDirectoryOnly))
        {
            if (bNoHidden && dir.Attributes.HasFlag(FileAttributes.Hidden))
                continue;

            dirs2scan.Add(dir);
        }
        dirs2scan.RemoveAt(scanIndex);
    }

如果需要,可以在函数中将sopt用作参数,如果不需要,可以将其删除。


1

我实际上更喜欢将函数参数传递给实现我想要的功能的方法。我有一个SearchDirectory方法,该方法构成了我使用的大多数调用的基础:

private void SearchDirectory(DirectoryInfo startDirectory, 
                             string pattern, 
                             Action<FileInfo> act)
{
    foreach (var file in startDirectory.GetFiles(pattern))
        act(file);

    foreach (var directory in startDirectory.GetDirectories())
        SearchDirectory(directory, pattern, act);
}

private List<FileInfo> SearchDirectory(DirectoryInfo startDirectory, 
                                       string pattern, 
                                       Func<FileInfo, bool> isWanted)
{
    var lst = new List<FileInfo>();
    SearchDirectory(startDirectory, 
                    pattern, 
                    (fi) => { if (isWanted(fi)) lst.Add(fi); });
    return lst;
}

然后,您可以使用列出的其他解决方案来编写一个IsHidden函数,该函数采用单个FileInfo,如果是,则返回true:

private bool IsHiddenDirectory(DirectoryInfo d) {
    if (d == null) return false;
    if (d.Attributes.HasFlag(FileAttributes.Hidden))) return true;
    if (d.Parent == null) return false;
    return IsHiddenDirectory(d.Parent);
}

private bool IsHidden(FileInfo fi) {
    if ((fi.Attributes & FileAttributes.Hidden) != 0) return true;
    // If you're worried about parent directories hidden:
    return IsHiddenDirectory(fi.Directory);
    // otherwise:
    return false;
}

然后,我可以很容易地用另一种方法调用它:

var files = SearchDirectory(new DirectoryInfo("C:\temp\"),
                            "*.xml",
                            (fi) => { return !IsHidden(fi); );

0
static bool IsHidden(string p)
{
 return p.Contains("Hidden");
}

DirectoryInfo directory = new DirectoryInfo(@"C:\temp");
FileInfo[] files = directory.GetFiles();

var filtered = files.Where(f => !IsHidden(File.GetAttributes(f).ToString()));

foreach (var f in filtered)
{
 Debug.WriteLine(f);
}

脚步:

  1. 创建在字符串包含“ Hidden”时返回true的布尔值---- static bool IsHidden(string p){return p.Contains("Hidden");}

  2. 获取目录信息---- DirectoryInfo directory = new DirectoryInfo(@"C:\temp");

  3. 从目录中获取文件信息数组---- FileInfo[] files = directory.GetFiles();

  4. 获取文件信息属性并从文件信息数组转换为字符串,并检查其是否包含“隐藏” ---- var filtered = files.Where(f=>!IsHidden(File.GetAttributes(f).ToString()));


1
您想解释一下
Ctznkane525 '18

如果您(Ctznkane525)有任何疑问,请检查此代码并回复我是否正确
Ujjwal Kashyap

1
不是我检查。网站上的程序,当您发布代码时解释代码...
fyi

我再解释一遍
Ujjwal Kashyap '18
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.