我的目录包含* .wav格式的近14,000,000个音频样本。
所有普通存储,没有子目录。
我想循环浏览文件,但是当我在该文件夹上使用DirectoryInfo.GetFiles()
时,整个应用程序会冻结几分钟!
这可以用另一种方式完成吗?也许阅读1000,处理它们,然后采取下一个1000,依此类推?
答案 0 :(得分:87)
您是否尝试过DirectoryInfo类的EnumerateFiles方法?
正如MSDN所说
EnumerateFiles
和GetFiles
方法的区别如下:当你 使用EnumerateFiles
,您可以开始枚举集合 返回整个集合之前的FileInfo
个对象;当你 使用GetFiles
,您必须等待整个FileInfo
个对象 在您可以访问阵列之前返回。因此,当你是 使用许多文件和目录,EnumerateFiles
可以更多 高效。
答案 1 :(得分:43)
在.NET 4.0中,Directory.EnumerateFiles(...)
是IEnumerable<string>
(而不是string[]
的{{1}}),因此它可以传输条目而不是缓冲所有条目;即。
Directory.GetFiles(...)
答案 2 :(得分:17)
您正在达到Windows文件系统本身的限制。当目录中的文件数量增加到大量(并且14M超出该阈值)时,访问目录变得非常慢。如果您一次读取一个文件或1000个文件并不重要,那只是目录访问。
解决此问题的一种方法是创建子目录并将文件拆分为组。如果每个目录都有1000-5000(猜测但你可以试验实际数字),那么你应该得到不错的性能打开/创建/删除文件。
这就是为什么如果你看一下像Doxygen这样为每个类创建一个文件的应用程序,他们会遵循这个方案并将所有内容放入两个使用随机名称的子目录级别。
答案 3 :(得分:6)
使用Win32 Api FindFile函数执行此操作而不会阻止该应用。
您还可以在System.Threading.Task(TPL)中调用Directory.GetFiles,以防止用户界面冻结。
答案 4 :(得分: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();
}
答案 5 :(得分:3)
我在很多时候都遇到了在单个目录中访问大文件的问题。子目录是一个很好的选择,但很快他们甚至不会提供太多的帮助。我现在要做的是创建一个索引文件 - 一个文件文件,其中包含目录中所有文件的名称(假设我在该目录中创建文件)。然后我读取索引文件,然后打开目录中的实际文件进行处理