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


当前回答

我更喜欢使用DirectoryInfo,因为我可以得到FileInfo的,而不仅仅是字符串。

        string baseFolder = @"C:\temp";
        DirectoryInfo di = new DirectoryInfo(baseFolder);

        string searchPattern = "*.xml";

        ICollection<FileInfo> matchingFileInfos = di.GetFiles(searchPattern, SearchOption.AllDirectories)
            .Select(x => x)
            .ToList();

我这样做的情况下,在未来我需要未来过滤..基于FileInfo的属性。

        string baseFolder = @"C:\temp";
        DirectoryInfo di = new DirectoryInfo(baseFolder);

        string searchPattern = "*.xml";

        ICollection<FileInfo> matchingFileInfos = di.GetFiles(searchPattern, SearchOption.AllDirectories)
            .Where(x => x.LastWriteTimeUtc < DateTimeOffset.Now)
            .Select(x => x)
            .ToList();

如果需要,我也可以求助于字符串。(仍然是未来证明过滤器/where-clause子句的东西。

        string baseFolder = @"C:\temp";
        DirectoryInfo di = new DirectoryInfo(baseFolder);

        string searchPattern = "*.xml";

        ICollection<string> matchingFileNames = di.GetFiles(searchPattern, SearchOption.AllDirectories)
            .Select(x => x.FullName)
            .ToList();

请注意,如果您想通过扩展文件,“.”是一个有效的搜索模式。

其他回答

简单的解决方案

string dir = @"D:\PATH";

DateTime from_date = DateTime.Now.Date;
DateTime to_date = DateTime.Now.Date.AddHours(23);
var files = Directory.EnumerateFiles(dir, "*.*",SearchOption.AllDirectories).Select(i=>new FileInfo(i))
.Where(file=>file.LastWriteTime >= from_date && file.LastWriteTime <= to_date);
foreach(var fl in files)
    Console.WriteLine(fl.FullName);

在Framework 2.0中,你可以使用(它列出根文件夹的文件,这是最好的最流行的答案):

static void DirSearch(string dir)
{
    try
    {
        foreach (string f in Directory.GetFiles(dir))
            Console.WriteLine(f);
        foreach (string d in Directory.GetDirectories(dir))
        {
            Console.WriteLine(d);
            DirSearch(d);
        }

    }
    catch (System.Exception ex)
    {
        Console.WriteLine(ex.Message);
    }
}

如果您只需要文件名,并且由于我不喜欢这里的大多数解决方案(特性或可读性方面),那么这个懒惰的解决方案如何?

private void Foo()
{
  var files = GetAllFiles("pathToADirectory");
  foreach (string file in files)
  {
      // Use can use Path.GetFileName() or similar to extract just the filename if needed
      // You can break early and it won't still browse your whole disk since it's a lazy one
  }
}

/// <exception cref="T:System.IO.DirectoryNotFoundException">The specified path is invalid (for example, it is on an unmapped drive).</exception>
/// <exception cref="T:System.UnauthorizedAccessException">The caller does not have the required permission.</exception>
/// <exception cref="T:System.IO.IOException"><paramref name="path" /> is a file name.-or-A network error has occurred.</exception>
/// <exception cref="T:System.IO.PathTooLongException">The specified path, file name, or both exceed the system-defined maximum length. For example, on Windows-based platforms, paths must be less than 248 characters and file names must be less than 260 characters.</exception>
/// <exception cref="T:System.ArgumentNullException"><paramref name="path" /> is null.</exception>
/// <exception cref="T:System.ArgumentException"><paramref name="path" /> is a zero-length string, contains only white space, or contains one or more invalid characters as defined by <see cref="F:System.IO.Path.InvalidPathChars" />.</exception>
[NotNull]
public static IEnumerable<string> GetAllFiles([NotNull] string directory)
{
  foreach (string file in Directory.GetFiles(directory))
  {
    yield return file; // includes the path
  }

  foreach (string subDir in Directory.GetDirectories(directory))
  {
    foreach (string subFile in GetAllFiles(subDir))
    {
      yield return subFile;
    }
  }
}

一个简单干净的解决方案

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

这就是我们如何将文件作为其子目录的FileInfo,

var dir = new DirectoryInfo(rootPath);
FileInfo[] files = dir.GetFiles("*.*", SearchOption.AllDirectories);