簡體   English   中英

C# - 獲取不包括隱藏文件的文件列表

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

Directory.GetFiles()返回所有文件,甚至是那些標記為隱藏的文件。 有沒有辦法獲取排除隱藏文件的文件列表?

這應該適合你:

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

使用.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有點懶。 但是,如果你枚舉一切,這不是很有用。

(這里是讓查詢更具可重復性)。

如果使用:

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

這只是為了讀取隱藏文件

一行代碼:

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

如果您正在使用SearchOption.TopDirectoryOnly - 那么它相對簡單 - 如果您想使用SearchOption.AllDirectories遞歸列出所有文件,它會變得復雜得多。 如果你可以GetFiles然后過濾掉只讀,但不幸的是它不能用於標記為隱藏的目錄。 該文件夾下的文件也會被列出,但與目錄不同,它們不會被隱藏。

您也可以同時使用GetDirectories - 您無法使用SearchOption.AllDirectories以遞歸方式列出所有內容,因為它還列出了隱藏在隱藏文件夾下的文件夾,但這些文件夾沒有啟用隱藏屬性。

至少對於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,如果不需要,則可以刪除。

我實際上更喜歡將函數參數傳遞給我想要的方法。 我有一個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); );
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. 創建bool,當string包含'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()));

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM