C# 从大型目录中高效地随机枚举文件

C# 从大型目录中高效地随机枚举文件,c#,fast-enumeration,C#,Fast Enumeration,我希望能够从目录中递归地枚举具有特定搜索模式(例如,*.txt)的文件。但有几个限制: 这个机制应该非常有效。目标是逐个枚举文件(使用IEnumerable),这样,如果有一个巨大的文件列表,则不需要花费很长时间来获取一个文件进行处理 枚举应该随机返回文件,这样,如果我的程序的两个实例正在尝试枚举目录,那么它们不应该以相同的顺序看到文件 考虑到这些需求,它看起来很有希望,只是它没有满足第二个需求。如果我不考虑性能问题,那么解决方案很简单(只需获取整个集合并在访问之前随机化序列) 有人能为.net

我希望能够从目录中递归地枚举具有特定搜索模式(例如,*.txt)的文件。但有几个限制:

  • 这个机制应该非常有效。目标是逐个枚举文件(使用IEnumerable),这样,如果有一个巨大的文件列表,则不需要花费很长时间来获取一个文件进行处理
  • 枚举应该随机返回文件,这样,如果我的程序的两个实例正在尝试枚举目录,那么它们不应该以相同的顺序看到文件
  • 考虑到这些需求,它看起来很有希望,只是它没有满足第二个需求。如果我不考虑性能问题,那么解决方案很简单(只需获取整个集合并在访问之前随机化序列)


    有人能为.net 3.5/4.0中的C#实现提供一些可能的选择吗?

    您所要求的是不可能的

    真正的“随机”枚举(即顺序可能每次都会改变)需要“选择而不替换”策略。这样的策略必然需要两个池:一个是“选择的”文件,另一个是“未关闭的”。必须先填充“未关闭的”列表,然后才能随机“选择”其中的任何内容。这违反了您的#1要求

    关于如何解决问题的两个想法:

  • 两个实例以相同的顺序查看文件有什么问题?如果是文件锁定问题,请选择只读锁定

  • 你也许可以用“保留桩”的方法逃脱。在这里,您可以创建自己的枚举器类,该类首先将少量FileInfo记录读取到“Hold”集合中。然后,每次调用代码请求一个文件时,它要么直接从EnumerateFiles中输入一个文件,要么从EnumerateFiles中读取一个文件,但将其与“Hold”堆中的一个文件交换并返回该文件。这个决定是随机的,直到EnumerateFiles没有返回任何内容,此时您将清空保留堆。这不会提供一个真正的随机选择顺序,但可能会增加足够的模糊性,以满足您的需求。“Hold”集合的最大大小可以根据口味进行调整,以平衡您对“随机性”的需求和快速获取第一个文件的需求


  • 要求2的目的是什么?如果您试图避免读/写争用,这似乎是实现这一点最糟糕的方法。。。