gpt4 book ai didi

c# - 读取大量文件 "at the same time"

转载 作者:行者123 更新时间:2023-11-30 23:33:06 24 4
gpt4 key购买 nike

我正在使用 FileSystemWatcher 来捕获每个createdchangeddeleted重命名 更改文件夹中的任何文件。

对于这些更改,我需要对这些文件的内容执行一个简单的校验和。简单地说,我正在打开一个文件流并将其传递给 MD5 类:

private byte[] calculateChecksum(string frl)
{
using (FileStream stream = File.Open(frl, FileMode.Open, FileAccess.Read, FileShare.ReadWrite))
{
return this.md5.ComputeHash(stream);
}
}

问题在于我需要处理的文件数量。例如,假设我在一个文件夹中创建了 200 个文件,然后我将它们全部复制并粘贴到同一个文件夹中。此操作将导致 200 个事件和 200 个 calculateChecksum() 执行。

我该如何解决这类问题?

最佳答案

FileSystemWatcher 处理程序中,将任务放入队列,由某些工作人员处理。 Worker 可以以目标速度或/和频率处理校验和计算任务。一个工作人员可能会更好,因为许多读者可以通过多次读取来减慢硬盘速度。

尝试阅读 BlockingCollection: https://msdn.microsoft.com/ru-ru/library/dd997371(v=vs.110).aspx

和生产者-消费者数据流模式 https://msdn.microsoft.com/ru-ru/library/hh228601(v=vs.110).aspx

var workerCount = 2;
BlockingCollection<String>[] filesQueues= new BlockingCollection<String>[workerCount];

for(int i = 0; i < workerCount; i++)
{
filesQueues[i] = new BlockingCollection<String>(500);

// Worker
Task.Run(() =>
{
while (!filesQueues[i].IsCompleted)
{
string url;

try
{
url= filesQueues[i].Take();
}
catch (InvalidOperationException) { }

if (!string.IsNullOrWhiteSpace(url))
{
calculateChecksum(url);
}
}
}
}

//FileSystemWatcher 处理程序内部

    var queueIndex = hash(filename) % workersCount
// Warning!!
// Blocks if numbers.Count == dataItems.BoundedCapacity
filesQueues[queueIndex].Add(fileName);
filesQueues[queueIndex].CompleteAdding();

您也可以创建多个消费者,只需同时调用 Take 或 TryTake - 每个项目只会被一个消费者消费。但考虑到在这种情况下一个文件可以由许多工作人员处理,并且多个硬盘读取器可以减慢硬盘速度。

UPD 在多个 worker 的情况下,最好创建多个 BlockingCollection,并将文件推送到具有索引的队列中:

关于c# - 读取大量文件 "at the same time",我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34062860/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com