【问题标题】:C# directory.getfiles memory helpC# directory.getfiles 内存帮助
【发布时间】:2009-12-28 17:43:07
【问题描述】:

这是我正在使用的代码:

using (StreamWriter output = new StreamWriter(Path.Combine(masterdestination, "Master.txt")))
{
     string masterfolders = sourcefolder1;
     string[] filess = Directory.GetFiles(masterfolders, "*.txt");
     foreach (string file in filess)
     {
        output.WriteLine(Path.GetFileName(file));
     }
}  

此代码将搜索用户指定目录中的所有文件以查找任何 txt 文件。这些目录有时包含 200 万个文件。

在此进程运行时对其进行监控,我发现它的内存使用量攀升至 800MB。有没有办法可以保持这个过程的速度并限制它使用的内存?还是让它读取并转储并继续?哈希表?任何想法都会很棒。

【问题讨论】:

  • 为什么 1mb 的内存使用是个问题?超过一百万个文件?

标签: c#


【解决方案1】:

Directory.GetFiles 真的很烂。如果您可以使用 .NET 4.0,您应该考虑使用 Directory.EnumerateFiles。来自文档:

EnumerateFiles 和 GetFiles 方法不同如下:当您 使用 EnumerateFiles,你可以开始 枚举名称的集合 在整个集合之前 回来;当你使用 GetFiles 时,你 必须等待整个名称数组 在您访问之前被退回 数组。因此,当你 处理许多文件和 目录,EnumerateFiles 可以是 更高效。

【讨论】:

  • 我不知道他们会添加这个。不错!
  • @BFree- 确实更好!这是我期待的 .NET 4.0 中的一件事!
  • 我相信 .Net 的单声道实现也有这个,所以如果 .Net 4 不是一个选项,你可以使用单声道库来迭代文件。
  • 不,我希望,.net 4.0 不是一个选项,因为我必须在所有客户端服务器上安装
  • 我不知道这是否有效,但我要投票,.net 4.0 并不能帮助我,但我认为它会有效。
【解决方案2】:

如果您正在实施搜索,那么我建议您使用Windows Search 4.0

【讨论】:

    【解决方案3】:

    如果您不能使用 Fx4,您最好编写自己的 FileEnumerator。这里是one example

    【讨论】:

    • +1。我打算建议这样的事情作为替代方案。我认为 CodeProject 也有类似的东西。
    【解决方案4】:

    Directory.GetFiles 必须在返回之前构建所有匹配文件的列表。只有这样,您才能枚举它们。所以当然,当有很多匹配的文件时,它是昂贵的。它甚至可以在内部构建所有文件的列表。

    如果您可以使用 .NET 4.0,那么您可以使用 Directory.EnumerateFiles 通过一次返回一个文件来避免此问题。如果你不能,那么我建议你用 C++ 而不是 C# 编写它。

    在 C++ 中,您可以使用 FindFirstFile,它还会一次将文件返回给您。

    // iterate though the files in this directory
    //
    TCHAR szWild[MAX_PATH];
    PathCombine(szWild, masterfolders, _T("*.txt"));
    
    WIN32_FIND_DATA fd;
    HANDLE hFind = FindFirstFile(szWild, &fd);
    if (INVALID_HANDLE_VALUE != hFind)
    {
       do {
       TCHAR szFileName[MAX_PATH];
       PathCombine(szFileName, masterfolders, fd.cFileName);
    
       // write szFilename to output stream..
    
       } while (FindNextFile(hFind, &fd));
    
       FindClose (hFind);
    }
    

    【讨论】:

    • 不确定 TCHAR 和 WIN32_FInD-Data 正在使用或引用什么。
    • 这是纯 Win32 C++ 代码。 #include "Windows.h" 用于大多数类型和原型。如果我没记错的话,PathCombine 来自 Shlwapi.h。
    【解决方案5】:

    正如答案here 中提到的,如果使用.NET 4.0,您可以使用Directory 类上的静态EnumerateFiles 方法来获取IEnumerable<string> 而不是字符串[],这会导致所有内存消耗。

    如果您使用的是 .NET 4.0 之前的 .NET 版本,您可以通过 P/Invoke 层调用 FindFirstFileEx、FindNextFile 等方法轻松模仿此功能。

    然后,对于从调用 FindFirstFile/FindNextFile 返回的每个文件,您将 yield 返回该项目。

    这将减少内存消耗,因为 EnumerateFiles 会减少具有大量文件的目录的内存消耗,因为您不会预先将它们全部加载到数组中,而是在找到它们时让它们进行处理。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-03-28
      • 1970-01-01
      • 2016-12-21
      • 2011-07-07
      • 2011-02-18
      相关资源
      最近更新 更多