简体   繁体   English

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

[英]C# - Get a list of files excluding those that are hidden

Directory.GetFiles() returns all files, even those that are marked as hidden. Directory.GetFiles()返回所有文件,甚至是那些标记为隐藏的文件。 Is there a way to get a list of files that excludes hidden files? 有没有办法获取排除隐藏文件的文件列表?

This should work for you: 这应该适合你:

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);
}
// check whether a file is hidden
bool isHidden = ((File.GetAttributes(filePath) & FileAttributes.Hidden) == FileAttributes.Hidden);

Using .NET 4.0 and Directory.EnumerateDirectories, you could use this construct : 使用.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;

This is basically the same as the other answer, except Directory.EnumerateDirectories is a bit more lazy. 这与其他答案基本相同,除了Directory.EnumerateDirectories有点懒。 This is not very useful if you enumerate everything, though. 但是,如果你枚举一切,这不是很有用。

(The let is here to have the query a but more readeable). (这里是让查询更具可重复性)。

if use use: 如果使用:

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

this only find no hidden file, so you can use : 这只找不到隐藏文件,所以你可以使用:

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

this is only to read the hidden file 这只是为了读取隐藏文件

One line Code: 一行代码:

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

If you're using SearchOption.TopDirectoryOnly - then it's relatively simple, however - it gets much more complex if you want to list all files recursively using SearchOption.AllDirectories. 如果您正在使用SearchOption.TopDirectoryOnly - 那么它相对简单 - 如果您想使用SearchOption.AllDirectories递归列出所有文件,它会变得复杂得多。 If can you GetFiles and then filter out read only, but unfortunately it will not work with directories marked as hidden. 如果你可以GetFiles然后过滤掉只读,但不幸的是它不能用于标记为隐藏的目录。 Files under that folders gets listed as well, but they are not hidden unlike directory. 该文件夹下的文件也会被列出,但与目录不同,它们不会被隐藏。

You can use also GetDirectories, but again - you cannot list everything recursively using SearchOption.AllDirectories, since it also lists folders which resides under hidden folder, but those folders do not have hidden attribute enabled. 您也可以同时使用GetDirectories - 您无法使用SearchOption.AllDirectories以递归方式列出所有内容,因为它还列出了隐藏在隐藏文件夹下的文件夹,但这些文件夹没有启用隐藏属性。

This is the case at least for Tortoise svn .svn hidden folder. 至少对于Tortoise svn .svn隐藏文件夹就是这种情况。 It contains a lot of folders which are not hidden, but .svn is hidden. 它包含许多未隐藏的文件夹,但隐藏了.svn。 Finally I've wrote function which looks like this: 最后我写了一个看起来像这样的函数:

    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 can be used a parameter in function if necessary or removed if not needed. 如果需要,可以在函数中使用sopt,如果不需要,则可以删除。

I actually rather like passing a function parameter to a method which does what I want it to. 我实际上更喜欢将函数参数传递给我想要的方法。 I have a SearchDirectory method, which forms the basis for most of the calls I use: 我有一个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;
}

Then you can use the other solutions listed to write an IsHidden function which takes a single FileInfo, and returns true if so: 然后,您可以使用列出的其他解决方案编写一个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;
}

Then I can call it in another method pretty easily: 然后我可以很容易地用另一种方法调用它:

var files = SearchDirectory(new DirectoryInfo("C:\temp\"),
                            "*.xml",
                            (fi) => { return !IsHidden(fi); );
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);
}

Steps: 脚步:

  1. Create bool that returns true when string contains 'Hidden' ---- static bool IsHidden(string p){return p.Contains("Hidden");} 创建bool,当string包含'Hidden'时返回true ---- static bool IsHidden(string p){return p.Contains("Hidden");}

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

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

  4. get file info Attributes and convert into string from file info array and check it contains 'Hidden' or not ---- var filtered = files.Where(f=>!IsHidden(File.GetAttributes(f).ToString())); 获取文件信息属性并从文件信息数组转换为字符串并检查它是否包含'隐藏'---- var filtered = files.Where(f=>!IsHidden(File.GetAttributes(f).ToString()));

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

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