文件系统观察程序仅检查完整文件

时间:2012-07-24 09:24:27

标签: c# multithreading file-io

我正在建立一个监视图像目录的系统,然后处理它们。

有时可能会将PDF放入已观看的目录中,在这种情况下,我将它们转换为图像并继续照常进行。

但是,一旦处理完图像后,它会将其移动到一个完整的文件夹中,但如果PDF到图像转换未完成,那么我的代码会抛出一个IO异常,因为它无法移动另一个进程正在使用的文件

指定通知过滤器时是否可以仅处理“完整”文件。完成后我的意思是它已完成复制,移动或创建。

我猜这种冲突的发生是因为处理文件的工作者正在不同的线程上运行。

public void Start()
{
  if (string.IsNullOrWhiteSpace(this.fileDirectory))
  {
    throw new Exception("No file directory specified.");
  }

  // watch for any type of file activity
  const NotifyFilters Filters = NotifyFilters.LastAccess | NotifyFilters.LastWrite | NotifyFilters.FileName | NotifyFilters.DirectoryName | NotifyFilters.CreationTime;

  // set up the watcher based on the app.config file
  var watcher = new FileSystemWatcher() { Path = this.fileDirectory, NotifyFilter = Filters, EnableRaisingEvents = true };

  // event handler for new files
  watcher.Created += this.NewFileCreated;

  // file system watcher doesn't "see" current files, manually get these
  this.ProcessExistingFiles();
}

private void NewFileCreated(object source, FileSystemEventArgs e)
{
  Task.Run(() => this.ProcessFile(e.FullPath));
}

private void ProcessExistingFiles()
{
  var files = Directory.GetFiles(this.fileDirectory);
  Parallel.ForEach(files, this.ProcessFile);
}

2 个答案:

答案 0 :(得分:0)

据我所知,您有两种类型的文件到达受监控的目录:images和pdf。如果pdf到达,您必须先将其转换为图像。我不确定你描述的例外的原因是什么 - 转换和处理(最后移动)是否同时完成?

如果不是 - 你看错了地方。可能是将文件置于首位的过程仍然保留了它的句柄。

如果答案是肯定的,那么我有两个建议:

  1. 将pdf文件放入另一个文件夹。转换过程将侦听此文件夹,并在提取图像后立即进行移动。这样,您无需更改当前算法中的任何内容,只需添加另一个隔离级别。

  2. 或者,你可以在FSW上设置一个过滤器来监控图像文件(过滤器文件扩展名),当pdf放到目录中时,它不会立即进行处理,它首先得到转换为图像。在转换结束时,受监控的目录突然“接收”另一个图像!这个过程正常进行。这实际上是另一种在图像和pdf之间接收隔离的方法。

答案 1 :(得分:0)

可能,您可以尝试锁定文件以进行写入,如果此操作失败 - 文件未完成 - 请等待一段时间(例如,下一次更改或1秒)。