对于我的WPF项目,我必须在单个目录(可能有子目录)中计算总文件大小.
样品1
DirectoryInfo di = new DirectoryInfo(path);
var totalLength = di.EnumerateFiles("*.*", SearchOption.AllDirectories).Sum(fi => fi.Length);
if (totalLength / 1000000 >= size)
return true;
Run Code Online (Sandbox Code Playgroud)
样本2
var sizeOfHtmlDirectory = Directory.GetFiles(path, "*.*", SearchOption.AllDirectories);
long totalLength = 0;
foreach (var file in sizeOfHtmlDirectory)
{
totalLength += new FileInfo(file).Length;
if (totalLength / 1000000 >= size)
return true;
}
Run Code Online (Sandbox Code Playgroud)
两个样本都有效.
样品1在更快的时间内完成.我没有准确计时,但在我的电脑上,使用相同内容/文件大小的相同文件夹,样本1需要几秒钟,样本2需要几分钟.
编辑
我应该指出,样品2中的瓶颈在foreach循环内!它快速读取GetFiles并快速进入foreach循环.
我的问题是,我怎么知道为什么会这样呢?
与其他答案所表明的相反,主要区别不是EnumerateFilesvs GetFiles- 它是DirectoryInfovs Directory- 在后一种情况下,你只有字符串并且必须分别创建新的FileInfo实例,这是非常昂贵的.
DirectoryInfo返回FileInfo使用缓存信息的FileInfo实例,而不是直接创建没有的新实例 - 这里和这里有更多细节.
相关报价(通过"旧的新事物"):
在NTFS中,文件系统元数据不是目录条目的属性,而是文件的属性,其中一些元数据作为调整复制到目录条目中以提高目录枚举性能.像FindFirstFile这样的函数报告目录条目,并且通过放置FAT用户习惯于"免费"获取的元数据,它们可以避免比目录列表的FAT慢.directory-enumeration函数报告上次更新的元数据,如果目录条目是陈旧的,则可能与实际元数据不对应.