的目录检索文件,我有一个包含支持* .wav格式的近1400万的音频采样目录。从包含大量文件
所有普通的存储,没有子目录。
我想遍历文件,但是当我在该文件夹上使用DirectoryInfo.GetFiles()
时,整个应用程序冻结了几分钟!
可以这样做另一种方式?也许读1000,处理它们,然后再拿1000等等?
的目录检索文件,我有一个包含支持* .wav格式的近1400万的音频采样目录。从包含大量文件
所有普通的存储,没有子目录。
我想遍历文件,但是当我在该文件夹上使用DirectoryInfo.GetFiles()
时,整个应用程序冻结了几分钟!
可以这样做另一种方式?也许读1000,处理它们,然后再拿1000等等?
您是否试过EnumerateFiles DirectoryInfo类的方法?
由于MSDN说
的
EnumerateFiles
和GetFiles
方法的区别如下:当您使用EnumerateFiles
,你可以返回整个集合之前开始枚举FileInfo
对象的集合;当您使用GetFiles
时,您必须等待FileInfo
对象的整个数组返回 ,然后才能访问该数组。因此,当你 许多文件和目录,EnumerateFiles
可以更有效地 。
+1有趣。不知道它存在。虽然它确实调用了内部包装在自定义枚举器中的相同API。 –
我的GetFiles方法只返回字符串,而不是FileInfo。 – MrFox
@MrFox '串DIR;' 'Directory.GetFiles' /'Directory.EnumerateFiles'返回字符串 '新DirectoryInfo的(DIR).getFiles' /'新DirectoryInfo的(DIR).EnumerateFiles'返回的FileInfo –
使用Win32 Api FindFile功能来做到这一点,而不会阻止应用程序。
您也可以在System.Threading.Task(TPL)中调用Directory.GetFiles以防止UI冻结。
您正在受到Windows文件系统本身的限制。当目录中的文件的数量增长到了大量的(和14M远远超出该阈值),访问目录变得慢得令人难以置信。一次读取一个文件或1000个文件并不重要,它只是目录访问。要解决这个
一种方法是创建子目录和文件分裂成组。如果每个目录有1000-5000(猜测但你可以试验实际的数字),那么你应该得到不错的表现打开/创建/删除文件。
这就是为什么如果你看看像Doxygen的,它为每个类创建一个文件的应用程序,他们按照这个方案,把一切都变成2级,其使用随机名的子目录。
在.NET 4.0,Directory.EnumerateFiles(...)
是IEnumerable<string>
(而不是Directory.GetFiles(...)
的string[]
),因此它可以流条目,而不是缓冲它们全部;即
foreach(var file in Directory.EnumerateFiles(path)) {
// ...
}
提及.NET 4的+1,这点很重要 – sll
有趣的一点...关键在于返回类型。 – SliverNinja
我打这个问题很多时间访问单个目录中的大文件。子目录是一个不错的选择,但是即使它们不提供太多帮助。我现在要做的就是创建一个索引文件 - 与目录中的所有文件名的文本文件(提供我创造在目录中的文件)。然后我读了索引文件,然后从目录中打开,然后实际的文件进行处理
享受。
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();
}
'的DirectoryInfo。如果您使用网络SAN,GetFiles()'也很糟糕。它锁定所有文件并阻止他人访问最近创建的SAN文件。我们从未找到过无阻塞的解决方案。 – SliverNinja
如果你在一个真正的perf临界点我也会考虑:http://stackoverflow.com/questions/724148/is-there-a-faster-way-to-scan-through-a-directory-recursively-in -net/724184#724184 –