如何递归列出所有文件在一个目录和子目录在c# ?


当前回答

这篇文章涵盖了您需要的所有内容。除了与搜索文件和比较名称不同,只需打印出名称。

可以这样修改:

static void DirSearch(string sDir)
{
    try
    {
        foreach (string d in Directory.GetDirectories(sDir))
        {
            foreach (string f in Directory.GetFiles(d))
            {
                Console.WriteLine(f);
            }
            DirSearch(d);
        }
    }
    catch (System.Exception excpt)
    {
        Console.WriteLine(excpt.Message);
    }
}

barlop添加

GONeale提到上面没有列出当前目录中的文件,并建议将文件列表部分放在获取目录的部分之外。下面的代码可以做到这一点。它还包括一个Writeline行,你可以取消注释,这有助于跟踪你在递归中的位置,这可能有助于显示调用,帮助显示递归是如何工作的。

            DirSearch_ex3("c:\\aaa");
            static void DirSearch_ex3(string sDir)
            {
                //Console.WriteLine("DirSearch..(" + sDir + ")");
                try
                {
                    Console.WriteLine(sDir);

                    foreach (string f in Directory.GetFiles(sDir))
                    {
                        Console.WriteLine(f);
                    }

                    foreach (string d in Directory.GetDirectories(sDir))
                    {
                        DirSearch_ex3(d);
                    }
                }
                catch (System.Exception excpt)
                {
                    Console.WriteLine(excpt.Message);
                }
            }

其他回答

一个简单干净的解决方案

/// <summary>
/// Scans a folder and all of its subfolders recursively, and updates the List of files
/// </summary>
/// <param name="sFullPath">Full path of the folder</param>
/// <param name="files">The list, where the output is expected</param>
internal static void EnumerateFiles(string sFullPath, List<FileInfo> fileInfoList)
{
    try
    {
        DirectoryInfo di = new DirectoryInfo(sFullPath);
        FileInfo[] files = di.GetFiles();

        foreach (FileInfo file in files)
            fileInfoList.Add(file);

        //Scan recursively
        DirectoryInfo[] dirs = di.GetDirectories();
        if (dirs == null || dirs.Length < 1)
            return;
        foreach (DirectoryInfo dir in dirs)
            EnumerateFiles(dir.FullName, fileInfoList);

    }
    catch (Exception ex)
    {
        Logger.Write("Exception in Helper.EnumerateFiles", ex);
    }
}

这篇文章涵盖了您需要的所有内容。除了与搜索文件和比较名称不同,只需打印出名称。

可以这样修改:

static void DirSearch(string sDir)
{
    try
    {
        foreach (string d in Directory.GetDirectories(sDir))
        {
            foreach (string f in Directory.GetFiles(d))
            {
                Console.WriteLine(f);
            }
            DirSearch(d);
        }
    }
    catch (System.Exception excpt)
    {
        Console.WriteLine(excpt.Message);
    }
}

barlop添加

GONeale提到上面没有列出当前目录中的文件,并建议将文件列表部分放在获取目录的部分之外。下面的代码可以做到这一点。它还包括一个Writeline行,你可以取消注释,这有助于跟踪你在递归中的位置,这可能有助于显示调用,帮助显示递归是如何工作的。

            DirSearch_ex3("c:\\aaa");
            static void DirSearch_ex3(string sDir)
            {
                //Console.WriteLine("DirSearch..(" + sDir + ")");
                try
                {
                    Console.WriteLine(sDir);

                    foreach (string f in Directory.GetFiles(sDir))
                    {
                        Console.WriteLine(f);
                    }

                    foreach (string d in Directory.GetDirectories(sDir))
                    {
                        DirSearch_ex3(d);
                    }
                }
                catch (System.Exception excpt)
                {
                    Console.WriteLine(excpt.Message);
                }
            }

一些改进版本,最大lvl下到目录和选项排除文件夹:

using System;
using System.IO;

class MainClass {
  public static void Main (string[] args) {

    var dir = @"C:\directory\to\print";
    PrintDirectoryTree(dir, 2, new string[] {"folder3"});
  }


  public static void PrintDirectoryTree(string directory, int lvl, string[] excludedFolders = null, string lvlSeperator = "")
  {
    excludedFolders = excludedFolders ?? new string[0];

    foreach (string f in Directory.GetFiles(directory))
    {
        Console.WriteLine(lvlSeperator+Path.GetFileName(f));
    } 

    foreach (string d in Directory.GetDirectories(directory))
    {
        Console.WriteLine(lvlSeperator + "-" + Path.GetFileName(d));

        if(lvl > 0 && Array.IndexOf(excludedFolders, Path.GetFileName(d)) < 0)
        {
          PrintDirectoryTree(d, lvl-1, excludedFolders, lvlSeperator+"  ");
        }
    }
  }
}

输入目录:

-folder1
  file1.txt
  -folder2
    file2.txt
    -folder5
      file6.txt
  -folder3
    file3.txt
  -folder4
    file4.txt
    file5.txt

函数的输出(由于lvl限制,folder5的内容被排除,folder3的内容被排除,因为它在excldedfolders数组中):

-folder1
  file1.txt
  -folder2
    file2.txt
    -folder5
  -folder3
  -folder4
    file4.txt
    file5.txt
IEnumerable<string> GetFilesFromDir(string dir) =>
 Directory.EnumerateFiles(dir).Concat(
 Directory.EnumerateDirectories(dir)
          .SelectMany(subdir => GetFilesFromDir(subdir)));

为了避免unauthoredaccessexception,我使用:

var files = GetFiles(@"C:\", "*.*", SearchOption.AllDirectories);
foreach (var file in files)
{
    Console.WriteLine($"{file}");
}

public static IEnumerable<string> GetFiles(string path, string searchPattern, SearchOption searchOption)
{
    var foldersToProcess = new List<string>()
    {
        path
    };

    while (foldersToProcess.Count > 0)
    {
        string folder = foldersToProcess[0];
        foldersToProcess.RemoveAt(0);

        if (searchOption.HasFlag(SearchOption.AllDirectories))
        {
            //get subfolders
            try
            {
                var subfolders = Directory.GetDirectories(folder);
                foldersToProcess.AddRange(subfolders);
            }
            catch (Exception ex)
            {
                //log if you're interested
            }
        }

        //get files
        var files = new List<string>();
        try
        {
            files = Directory.GetFiles(folder, searchPattern, SearchOption.TopDirectoryOnly).ToList();
        }
        catch (Exception ex)
        {
            //log if you're interested
        }

        foreach (var file in files)
        {
            yield return file;
        }
    }
}