从包含大量文件的目录中检索文件
我有目录,其中包含* .wav格式近14,000,000audio采样。
所有普通的存储,没有子目录。
我想遍历文件,但是当我在该文件夹上使用DirectoryInfo.GetFiles()
时,整个应用程序冻结了几分钟!
这可以做另一种方式吗? 也许读1000,处理它们,然后再拿1000等?
你有没有尝试过DirectoryInfo类的EnumerateFiles方法?
正如MSDN所言
EnumerateFiles
和GetFiles
方法的区别如下:使用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文件)。 然后我读取索引文件,然后打开目录中的实际文件进行处理