簡體   English   中英

如何在 C# 中將文件枚舉到僅 3 個文件目錄?

[英]How to EnumerateFiles to only 3 files directories in C#?

目前我只能 Enumeratefiles 方法所有文件或源目錄。 我希望它深入 3 個子目錄,然后只檢查那里。

例如,第二個片段將只檢查 K:\\SourceFolder

第一個示例將檢查 K:\\SourceFolder\\JobName\\Batches\\Folder1\\Folder11\\Images 它將檢查所有文件夾,從而降低應用程序的性能和效率。

我只需要它來檢查 K:\\SourceFolder\\JobName\\Batches

這段代碼走得太遠了:

            List<string> validFiles = new List<string>();
            List<string> files = Directory.EnumerateFiles(folderPath, "*.*", SearchOption.AllDirectories).ToList();
            foreach (var file in files)

這段代碼還不夠:

           List<string> files = Directory.Enumeratefiles(directory)

我們可以使用幾種不同的方法來處理此任務,因此我將列出一些示例以幫助開始。

使用循環迭代所有文件夾並僅返回目標深度的文件夾:

List<string> ListFilesAtSpecificDepth(string rootPath, int targetDepth)
{   
    // Set the root folder before we start iterating through subfolders.
    var foldersAtCurrentDepth = Directory.EnumerateDirectories(rootPath).ToList(); // calling ToList will make the enumeration happen now.
    
    for (int currentDepth = 0; currentDepth < targetDepth; currentDepth++)
    {
        // Using select many is a clean way to select the subfolders for multiple root folders into a flat list.
        foldersAtCurrentDepth = foldersAtCurrentDepth.SelectMany(x => Directory.EnumerateDirectories(x)).ToList();
    }
    
    // After the loop we have a list of folders for the targetDepth only.
    // Select many again to get all the files for all the folders.
    return foldersAtCurrentDepth.SelectMany(x => Directory.EnumerateFiles(x, "*.*", SearchOption.TopDirectoryOnly)).ToList();
}

另一種選擇是使用遞歸來調用相同的方法,直到我們達到所需的深度。 這可用於僅返回目標深度處的結果或沿途的所有結果,由於上面的示例僅針對目標深度,因此我決定使用自定義對象來跟蹤深度來為這個結果做所有結果:

class FileSearchResult
{
    public string FilePath {get;set;}
    public int FolderDepthFromRoot {get;set;}
}

List<FileSearchResult> ListFilesUntilSpecificDepth(string rootPath, int maxDepth, int currentDepth = 0)
{
    // Add all the files at the current level along with extra details like the depth.
    var iterationResult = Directory.EnumerateFiles(rootPath, "*.*", SearchOption.TopDirectoryOnly)
        .Select(x => new FileSearchResult 
        {       
            FilePath = x,
            FolderDepthFromRoot = currentDepth
        }).ToList();

    if (currentDepth < maxDepth) // we need to go deeper.
    {
        var foldersUnderMe = Directory.EnumerateDirectories(rootPath);

        // Add all the results for subfolders recursively by calling the same method again.
        foreach (var subFolder in foldersUnderMe)
        {
            iterationResult.AddRange(ListFilesUntilSpecificDepth(subFolder, maxDepth, currentDepth + 1))
        }
    }
    
    return iterationResult;
}

有了遞歸和循環的例子,我想談的最后一個是使用文件系統本身的結構來幫助完成這個任務。 因此,我們可以使用原始方法遞歸獲取所有文件,然后使用所有結果的列表來確定深度,而不是管理我們自己的循環或遞歸。 例如,我們知道“/”是文件系統用來分隔文件夾的字符,並且在文件夾或文件名中使用它是一個非法字符,因此使用此標記來有效地計算文件夾應該是非常安全的。 在這個例子中,我將使用另一個自定義類來跟蹤結果,因此它應該有效地返回與遞歸方法相同但具有無限深度的結果。

class FileSearchResult
{
    public string FilePath { get; set; }
    public int FolderDepthFromRoot { get; set; }
}

List<FileSearchResult> ListFiles(string rootPath)
{
    var allFiles = Directory.EnumerateFiles(rootPath, "*.*", SearchOption.AllDirectories).ToList();
    int numberOfFoldersInRootPath = rootPath.Count(c => c == '\\'); // count how many backslashes in root path as a base.

    return allFiles.Select(filePath => new FileSearchResult 
    {
        FilePath = filePath,
        FolderDepthFromRoot = filePath.Count(c => c == '\\') - numberOfFoldersInRootPath
    }).ToList();
}

暫無
暫無

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

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