如何并行观看大约 100 个文件夹? FileSystemWatcher 或其他更有效的选择?

How to watch around 100 folders in parallel? FileSystemWatcher or other more efficient options?

问题是,如何同时监视100个文件夹?

 class ExampleAttributesChangedFiringTwice
{
    public ExampleAttributesChangedFiringTwice(string demoFolderPath)
    {
        var watcher = new FileSystemWatcher()
        {
            Path = demoFolderPath,
            NotifyFilter = NotifyFilters.LastWrite,
            Filter = "*.txt"
        };

        watcher.Changed += OnChanged;
        watcher.EnableRaisingEvents = true;
    }

    private static void OnChanged(object source, FileSystemEventArgs e)
    {
        // extract zip file, do the validation, copy file into other destination
    }
}

目标文件夹,无论zip的源文件夹是同一个文件夹吗?即无论是来自Folder1还是Folder2,都会被提取到FolderX?

目标文件夹对所有“C:\ExtractedData”通用。

所以数据下的每个文件夹都会被监视?没有“列入黑名单”的文件夹?如果 zip 出现在数据本身而不是其子文件夹中怎么办?如果创建了一个新的子文件夹,它是否也应该被监视?

“zip”总是在“子文件夹”中,它永远不会在 Data 文件夹中创建。 是的,以后有机会,更多的子文件夹会来,需要观察。

提取的文件是根据其 zip 文件名进入目标文件夹内的单独子文件夹,还是直接提取到目标文件夹中,例如,如果是 A.zip,内容是否继续至 Target\A 或仅目标。

例如,如果 A.zip 包含 2 个文件,“1.txt”和“2.txt”,那么这两个文件都会转到“C:\ExtractedData” .这对于每个 zip 文件到达不同的子文件夹很常见。

“并行 100 个文件夹”部分原来是一个转移注意力的问题。由于所有新的 zip 文件无论出现在何处都被一视同仁,只需添加 IncludeSubdirectories=true 就足够了。注意以下代码容易出现异常,阅读评论

class WatchAndExtract
{
    string inputPath, targetPath;
    public WatchAndExtract(string inputPath, string targetPath)
    {
        this.inputPath = inputPath;
        this.targetPath = targetPath;
        var watcher = new FileSystemWatcher()
        {
            Path = inputPath,
            NotifyFilter = NotifyFilters.FileName,
            //add other filters if your 3rd party app don't immediately copy a new file, but instead create and write
            Filter = "*.zip",
            IncludeSubdirectories = true
        };
        watcher.Created += OnCreated; //use Changed if the file isn't immediately copied
        watcher.EnableRaisingEvents = true;
    }

    private void OnCreated(object source, FileSystemEventArgs e)
    {
        //add filters if you're using Changed instead 
        //
        ZipFile.OpenRead(e.FullPath).ExtractToDirectory(targetPath);
        //this will throw exception if the zip file is being written.
        //Catch and add delay before retry, or watch for LastWrite event that already passed for a few seconds
    }
}

如果它跳过了一些文件,您要么一次创建了太多文件and/or zip 太大而无法处理。要么increase the buffer size or start them in new thread。在 IO 繁忙或 zip 文件非常大的 HDD 上,事件可能会超过存储容量并在长时间繁忙后跳过文件,您将不得不考虑写入不同的物理(不仅仅是同一设备中的不同分区)驱动器反而。始终验证您的预测使用模式。