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 驱动器下载这些文件。在这种情况下,您将完全控制文件和获取文件的顺序。
我在我的 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 驱动器下载这些文件。在这种情况下,您将完全控制文件和获取文件的顺序。