我们是否有理由使用Directory.GetFiles()而不是Directory.EnumerateFiles()?

7

2
GetFiles是为了向后兼容而存在的。它最初出现在1.0版的.NET框架中。EnumerateFiles则是在之后的版本中引入的——如果我没记错的话,应该是4.0或4.5。 - Enigmativity
2
@Enigmativity GetFiles是在2.0中引入的,而EnumerateFiles是在4.0中引入的。 - Despertar
@Despertar - 感谢您的澄清。 - Enigmativity
3个回答

10
根据http://msdn.microsoft.com/en-us/library/07wt70x2%28v=vs.110%29.aspx网站的说明:

EnumerateFiles和GetFiles方法的区别如下:使用枚举文件时,你可以在整个集合返回之前开始枚举名称集合;而当你使用GetFiles方法时,必须等待整个名称数组返回后才能访问该数组。因此,当你处理多个文件和目录时,使用EnumerateFiles更有效率。

我猜GetFiles可被认为是一个便利函数。


1
根据MSDN的说法,GetFiles似乎并没有被弃用。它更像是一个方便的函数。虽然我没有看到明确的声明。 - AlexD
因此,本质上,GetFiles() 等同于 EnumerateFiles().ToList() - dwerner
3
实际上,查看参考代码GetFiles()最终调用了等效的EnumerateFiles(如果我理解正确的话),然后调用:new List<String>(fileIterator).ToArray()。如果我理解正确,这将产生_两个_ O(n) 操作,而EnumerateFiles().ToList()只会产生一个。 - Chris Sinclair
@Chris Sinclair - 哎呀,更糟糕了。 - dwerner
需要注意的一点是,如果您在文件夹中进行文件操作(例如重命名文件),同一个文件可能会被多次处理,因为当枚举器遍历目录时,它会再次“捕获”该文件。 - luizs81

10
你需要为不同的工作选择适当的工具。如果你只有少量文件,那么你可能想使用Directory.GetFiles()并将它们加载到内存中。
另一方面,如果你需要通过逐个枚举文件来节省内存,那么就需要使用Directory.EnumerateFiles()
这类似于是否将everythinglazy的争论。我认为这可以帮助我们明确事物的重要性,因为无缘无故地使所有东西都变得懒惰是过度的。
你需要在简单性和效率之间做出权衡。从概念上讲,一个枚举器并不实际包含文件,而是逐个产生它们,比一个字符串数组更加复杂。能够将该枚举器存储在IEnumerable<string>中是一个很好的抽象,但问题依然存在。
这也可能更难预测性能。使用GetFiles()时,你知道性能成本发生在调用该方法时。EnumerateFiles()在枚举之前不会执行任何操作。
意图很重要。如果您在一个您知道不会有太多文件的目录上使用EnumerateFiles(),那么您只是盲目地使用它而没有理解。计算机代码运行的环境也很重要。如果我在一台拥有24 GB RAM的服务器上运行某些东西,那么我可能更有可能使用像GetFiles()这样消耗内存的方法,而不是在一台只有1 GB RAM的服务器上运行。
如果您不知道将有多少文件或不确定代码将在哪种环境中运行,那么明智的做法是谨慎使用内存高效的版本。
有许多变量需要考虑,良好的程序员会考虑这些因素并有目的地执行操作。

4
这两种方法最终都会调用System.IO.FileSystemEnumerableFactory.CreateFileNameIterator()。唯一的区别似乎在于,GetFiles()的结果被包装在List中,然后转换为数组。因此,正如其他答案中提到的那样,区别在于enumerator已经通过GetFiles()遍历过了,而通过EnumerateFiles可以在遍历之前获取enumerator。
供参考,我使用ILSpy (http://ilspy.net/)找到了这个内容。

2
实际上,在BCL中的许多类中,您可以通过在线参考源查看源代码;这里不需要使用ILSpy。 - Chris Sinclair

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接