【问题标题】:Is there a reason why we would use Directory.GetFiles() over Directory.EnumerateFiles()?为什么我们会使用 Directory.GetFiles() 而不是 Directory.EnumerateFiles() 有什么原因吗?
【发布时间】:2014-08-25 07:18:35
【问题描述】:

我不确定我们为什么要使用 Directory.GetFiles,因为如果 Directory.EnumerateFiles 能够做同样的事情,并且您甚至可以在返回找到的整个目录列表之前枚举该列表。

What is the difference between Directory.EnumerateFiles vs Directory.GetFiles?

为什么,既然EnumerateFiles 可用,还需要使用GetFiles

【问题讨论】:

  • GetFiles 是为了向后兼容。它在最初的 1.0 .NET 框架中。 EnumerateFiles 是在很久以后才引入的——如果我没记错的话是 4.0 或 4.5。
  • @Enigmativity GetFiles 在 2.0 中引入,EnumerateFiles 在 4.0 中引入。
  • @Despertar - 感谢您的澄清。

标签: c# system.io.directory


【解决方案1】:

根据http://msdn.microsoft.com/en-us/library/07wt70x2%28v=vs.110%29.aspx

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

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

【讨论】:

  • @GrantWinney 根据 MSDN,GetFiles 听起来并没有被弃用。它看起来更像是一个便利功能。虽然我没有看到关于它的明确声明。
  • 所以,本质上,GetFiles() 等价于EnumerateFiles().ToList()
  • @dwerner:实际上,查看reference codeGetFiles() 最终会调用等效的EnumerateFiles(如果我没看错的话),然后调用:new List<String>(fileIterator).ToArray()。如果我理解正确,这会产生 two O(n) 操作,而 EnumerateFiles().ToList() 只会产生 one
  • @Chris Sinclair - 哎呀,更糟。
  • 有一点需要注意。如果您在文件夹中进行文件操作(例如重命名文件),同一个文件可能会被处理多个文件,因为它在枚举器遍历目录时再次被“捕获”。
【解决方案2】:

您使用正确的工具完成正确的工作。如果您有少量文件,那么您可能只想使用Directory.GetFiles() 并将它们加载到内存中。

Directory.EnumerateFiles() 另一方面,当您需要通过一次枚举文件来节省内存时。

这类似于是否使一切lazy 的论点,或者只是在适当的时候使用它。我认为这有助于正确看待事情,因为无缘无故地让一切变得懒惰是矫枉过正的。

您需要在简单性与效率之间进行权衡。从概念上讲,实际上不包含文件但一次生成一个的枚举器比字符串数组更复杂。能够将该枚举器存储在 IEnumerable<string> 中是一个很棒的抽象,但重点仍然存在。

预测性能也可能更加困难。使用GetFiles(),您知道调用该方法时会产生性能成本。 EnumerateFiles() 在被枚举之前不会做任何事情。

意图很重要。如果您在一个您知道不会有那么多文件的目录上使用EnumerateFiles(),那么您只是在不理解的情况下盲目使用它。运行代码的计算机也很重要。如果我在具有 24 GB RAM 的服务器上运行某些东西,那么与在具有 1 GB RAM 的服务器上相比,我可能更可能使用像 GetFiles() 这样的内存密集型方法。

如果您不知道会有多少文件或不确定代码将在哪种环境中运行,那么明智的做法是谨慎行事并使用内存效率高的版本。

有许多变量需要考虑,优秀的程序员会考虑这些因素并有目的地做事。

【讨论】:

    【解决方案3】:

    这两种方法最终都会调用 System.IO.FileSystemEnumerableFactory.CreateFileNameIterator()。唯一的区别似乎是 GetFiles() 结果被包装在一个 List 中,然后变成一个数组。因此,正如其他一些答案中所提到的,不同之处在于枚举器已经通过 GetFiles() 与 EnumerateFiles 进行了遍历,后者在遍历之前为您提供了枚举器。

    作为参考,我可以使用 ILSpy (http://ilspy.net/) 找到它

    【讨论】:

    • 其实BCL中的很多类都可以通过在线reference source查看源代码;无需在这里进行 ILSpy。
    猜你喜欢
    • 2011-08-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-02-18
    • 1970-01-01
    相关资源
    最近更新 更多