我认为这是一个相当普遍的问题,但是我没有设法找到一个好的解决方案或浏览这个论坛。
问题
我编写了一个工具来获取文件夹的文件列表,其中包含一些其他信息,例如文件名,文件路径,文件大小,哈希等。
我遇到的最大问题是某些文件夹包含数百万个文件(结构中可能有5000万个文件)。
可能的解决方案
我有两个解决方案,但它们都不理想。
每次读取文件时,信息都会直接写入文件。这没关系,但这意味着我无法对文件进行多线程处理,而不会遇到锁定文件的线程问题。
每次读取文件时,信息都会添加到某种形式的集合中,例如ConcurrentBag。我可以多线程化文件的枚举并将它们添加到集合中。枚举完成后,我可以使用File.WriteAllLines将整个集合写入文件;但是,在集合中添加5000万个条目会使大多数机器内存不足。
其他选项
是否有任何方法可以将项目添加到集合中,然后在它到达集合中的特定数量的记录时将其写入文件?或者类似的东西?
我查看了一个BlockingCollection,但由于生产者将是多线程的,因此填充速度非常快,但消费者只能是单线程的。
答案 0 :(得分:1)
创建一个由所有线程共享的FileStream。在写入该FileStream之前,线程必须将其锁定。 FileStream有一些缓冲区(如果我没记错的话,有4096字节),因此它实际上并不是每次都写入磁盘。如果4096字节还不够,你可以使用BufferedStream。
答案 1 :(得分:1)
BlockingCollection
正是您所需要的。您可以创建一个具有大缓冲区的文件,并使用一个写入程序线程写入一个文件,该文件在运行期间保持打开状态。
如果读取是主导操作,则整个时间队列将接近空,总时间将略微超过读取时间。
如果写入是占主导地位的操作,则队列将填满,直到达到您设置的限制(以防止内存不足的情况),并且生产者只会在作者前进时前进。总时间将是按顺序将所有记录写入单个文件所需的时间,并且您不能做得更好(当编写器是最慢的部分时)。
您可以通过多个阻止集合进行流水线操作,从而获得更好的性能,例如:使哈希计算(CPU绑定操作)可能与读取或写入操作分开。如果您想这样做,请考虑TPL DataFlow库。