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

我有目录,其中包含* .wav格式近14,000,000audio采样。

所有普通的存储,没有子目录。

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

这可以做另一种方式吗? 也许读1000,处理它们,然后再拿1000等?

你有没有尝试过DirectoryInfo类的EnumerateFiles方法?

正如MSDN所言

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

在.NET 4.0中, Directory.EnumerateFiles(...)IEnumerable<string> (而不是Directory.GetFiles(...)string[] ),所以它可以stream入条目而不是caching它们; 即

 foreach(var file in Directory.EnumerateFiles(path)) { // ... } 

你正在打击Windows文件系统本身的限制。 当一个目录中的文件数量增长到一个很大的数量(14M是远远超过这个阈值),访问目录变得非常慢。 如果您一次读取一个文件或1000个文件,这并不重要,它只是目录访问。

解决这个问题的一个方法是创build子目录并将文件拆分成组。 如果每个目录有1000-5000(猜测,但你可以尝试实际的数字),那么你应该得到不错的performance打开/创build/删除文件。

这就是为什么如果你看看像Doxygen这样的应用程序,它为每个类创build一个文件,他们遵循这个scheme,并把所有的东西放到两个使用随机名的子目录中。

使用Win32 Api FindFile函数来做到这一点,而不会阻止应用程序。

您也可以调用System.Threading.Task (TPL)中的Directory.GetFiles来防止您的UI冻结。

请享用。

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

我很多时候都遇到过在单个目录中访问大文件的问题。 子目录是一个不错的select,但是即使它们不提供太多的帮助。 我现在要做的就是创build一个索引文件 – 一个文本文件,其中包含目录中所有文件的名称(前提是我在该目录中创build文件)。 然后我读取索引文件,然后打开目录中的实际文件进行处理