从包含大量文件的目录中检索文件

edd*_*yuk 61 c# directory file getfiles

我的目录包含*.wav格式的近14,000,000个音频样本.

所有普通存储,没有子目录.

我想循环遍历文件,但是当我DirectoryInfo.GetFiles()在该文件夹上使用时,整个应用程序冻结了几分钟!

这可以换一种方式吗?也许阅读1000,处理它们,然后采取下一个1000,依此类推?

Har*_*san 88

您是否尝试过DirectoryInfo类的EnumerateFiles方法?

正如MSDN所说

EnumerateFilesGetFiles方法的区别如下:当你使用EnumerateFiles,你就可以开始列举的集合 FileInfo返回整个集合之前的对象; 在使用时GetFiles,必须等待FileInfo返回整个对象数组,然后才能访问该数组.因此,当您使用许多文件和目录时,EnumerateFiles可以更高效.

  • +1有趣.不知道它存在.虽然它确实调用内部包含在自定义枚举器中的相同API. (4认同)

Mar*_*ell 44

在.NET 4.0,Directory.EnumerateFiles(...)IEnumerable<string>(而不是string[]Directory.GetFiles(...)),因此它可以流条目,而不是缓冲它们全部; 即

foreach(var file in Directory.EnumerateFiles(path)) {
    // ...
}
Run Code Online (Sandbox Code Playgroud)

  • 提及.NET 4的+1,这是重要的一点 (3认同)

DXM*_*DXM 17

你正在达到Windows文件系统本身的限制.当目录中的文件数量增加到大量(并且14M超出该阈值)时,访问目录变得非常慢.如果您一次读取一个文件或1000个文件并不重要,那只是目录访问.

解决此问题的一种方法是创建子目录并将文件拆分为组.如果每个目录都有1000-5000(猜测但你可以试验实际数字),那么你应该获得不错的性能打开/创建/删除文件.

这就是为什么如果你看看像Doxygen这样的应用程序,它为每个类创建一个文件,他们遵循这个方案并将所有内容放入使用随机名称的2个子目录级别.


Muh*_*han 6

使用Win32 Api FindFile函数可以在不阻止应用程序的情况下执行此操作.

您还可以在System.Threading.Task(TPL)中调用Directory.GetFiles 以防止UI冻结.


Jar*_*ryn 5

请享用.

    public List<string> LoadPathToAllFiles(string pathToFolder, int numberOfFilesToReturn)
    {
        var dirInfo = new DirectoryInfo(pathToFolder);
        var firstFiles = dirInfo.EnumerateFiles().Take(numberOfFilesToReturn).ToList();
        return firstFiles.Select(l => l.FullName).ToList();
    }
Run Code Online (Sandbox Code Playgroud)