【问题标题】:Best way to get path all files, subfolder in large directory?获取路径所有文件的最佳方法,大目录中的子文件夹?
【发布时间】:2019-02-08 01:36:26
【问题描述】:

下面是我获取大目录中所有文件的代码(框架 3.5)。它运行约 1 小时,但无法完成,任务管理器中的内存高达 1,600,000K

void ApplyAllFiles(DirectoryInfo dir)
{
    String space = "          ";
    foreach (FileInfo f in dir.GetFiles())
    {
        try
        {            
            int size = Convert.ToInt32(f.Length / 1024);
            if (size > filesize && isFileType(f.FullName) == true)
            {
                pw.WriteLine(f.LastWriteTime + space + size + space + f.FullName);
            }
        }
        catch
        { }
    }
    foreach (DirectoryInfo d in dir.GetDirectories())
    {
        try
        {
            ApplyAllFiles(d);
        }
        catch
        {

        }
    }
}

如果我使用 Java 代码,只需 5 分钟即可完成,内存总是


我通过在 TRY { } 中使用 FOREACH 循环来解决它。

【问题讨论】:

  • 你试过Directory.GetFiles(dirPath, "*", SearchOption.AllDirectories) 吗?
  • 写空的 catch 块总是一个坏主意。
  • 您可能希望在此处利用 DirectoryInfo.EnumerateDirectoriesDirectoryInfo.EnumerateFiles
  • @John,什么时候是个好主意?
  • @kienvu GetFiles 如果文件太多,会抛出内存不足。如果您遇到访问错误,请改用EnumerateFiles 并尝试以管理员身份运行程序。

标签: c# recursion directory filepath


【解决方案1】:

你可以创建一个非递归的扩展方法:

public static IEnumerable<FileInfo> GetFilesDepthFirst(this DirectoryInfo root,
    string dirPattern = "*", string filePattern = "*.*")
{
    var stack = new Stack<DirectoryInfo>();
    stack.Push(root);
    while (stack.Count > 0)
    {
        var current = stack.Pop();
        IEnumerable<FileInfo> files = Enumerable.Empty<FileInfo>();
        IEnumerable<DirectoryInfo> dirs = Enumerable.Empty<DirectoryInfo>();

        try
        {
#if NET35
            dirs = current.GetDirectories(searchPattern: dirPattern);
            files = current.GetFiles(searchPattern: filePattern);
#else
            dirs = current.EnumerateDirectories(searchPattern: dirPattern);
            files = current.EnumerateFiles(searchPattern: filePattern);                  
#endif
        }
        catch (UnauthorizedAccessException) { }
        catch (PathTooLongException) { }

        foreach (FileInfo file in files)
            yield return file;

        foreach (DirectoryInfo dir in dirs)
            stack.Push(dir);
    }
}

你可以这样称呼:

var dInfo = new DirectoryInfo("C:\\");
var allFiles = dInfo.GetFilesDepthFirst(filePattern: "*.txt");
foreach(FileInfo file in allFiles)
{
    // build output string
}

【讨论】:

  • 感谢您的帮助,但我使用的是框架 3.5,方法 Directory.EnumerateDirectories/Files 没有退出
  • @kienvu 您仍然可以在我之前发布的内容中使用.GetFilesGetDirectories,只是效率可能会稍低一些。我将更新以显示此选项..
  • 我通过在 try{ } 中执行 foreach 循环来解决它。也许我无法获取某些文件路径,但代码运行良好
【解决方案2】:

正如其他用户所说,Directory.GetFiles 很糟糕。 Directory.EnumerateFilesalternative

来自here的参考

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2016-12-12
    • 2023-03-31
    • 1970-01-01
    • 2011-08-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多