FileSystemWatcher 排序算法

FileSystemWatcher sort algorithm

我在我的 PC 上 运行 创建了一个简单的 FileSystemWatcher 服务:

    public static void Run()
    {

        var watcher = new FileSystemWatcher
        {
            Path = @"C:\Users\XXX\Google Drive",
            NotifyFilter = NotifyFilters.LastAccess
                           | NotifyFilters.LastWrite
                           | NotifyFilters.FileName
                           | NotifyFilters.DirectoryName,

            Filter = "*.*",
        };

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

    private static void OnChanged(object source, FileSystemEventArgs e)
    {
        FooPrintClass.SendToPrinter(e.FullPath);
    }

如您所见,我正在查看 Google 云端硬盘文件夹。该文件夹也在我的服务器上同步。我服务器上的系统有时会创建 2 对名称相同但类型不同的文件:

(Foo.pdf, Foo.txt)

有时系统会创建 50 多个这样的对,它们都会同步到我的 Google Drive 文件夹。

到目前为止一切顺利,现在是我的问题: 我的 FileSystemWatcher 服务确实按预期工作,但它根本不对它们进行任何排序。 我需要我的服务一次实际处理每一对。

Expected Result:
Foo.pdf, Foo.txt
Bar.pdf, Foo.txt

Actual Result: 
Bar.txt, Foo.pdf
Foo.txt, Bar.pdf

如预期结果所示,我需要先按顺序打印对。 有很多方法可以实现 "queue" 解决方案,但就我而言,我不知道会有多少文件。所以我不知道文件的总数,因此构建队列和排序算法会更难。

有什么建议吗?

您可以使用 Reactive Extensions 来缓冲一些事件并在继续之前对它们进行排序。

一个例子是这样的:

Observable
    .FromEventPattern<FileSystemEventArgs>(watcher, "Created")
    .Buffer(TimeSpan.FromSeconds(10))
    .Subscribe(onNext);

public void onNext(IList<string>) { ... }

该示例缓冲了 10 秒内发生的所有更改,并将它们作为列表传递给 onNext。这允许您在执行任何其他操作之前对文件进行排序。

这忽略了一些边缘情况,例如在缓冲区 window 结束时正在创建文件。但是有多种方法可以解决这些问题。

当您使用 3d 派对系统同步文件时,您无法控制它是如何完成的。您可能会遇到问题 - 无法控制它们的同步顺序,无法保证当您从您的监视中收到通知时文件未被锁定。

为简化同步顺序问题,您可以捆绑同步文件。 如果您可以修改创建这些文件的系统,则可以将这两个文件压缩到一个 zip 文件中。有了 Foo.zip,您就可以按您想要的顺序打印这两个文件。

它没有解决可能锁定的问题。如果您能以某种方式通知您的服务一对新文件,您可以使用 API 直接从 Google 驱动器下载这些文件。在这种情况下,您将完全控制文件和获取文件的顺序。