【问题标题】:Check if TIFF file scanning is complete检查 TIFF 文件扫描是否完成
【发布时间】:2011-11-16 16:20:31
【问题描述】:

我有一个 FileSystemWatcher 监视从扫描设备接收 TIF 文件的目录。

必须检查扫描过程是否完成,然后处理完全扫描的文件,否则我的程序将处理一个不完整的文件。

我有类似的东西:

private void OnFileCreated(...)
{
    while(IsFileLocked(path))
        Thread.Sleep(time);

    // OK to read
}

这是正在发生的事情:

- Scanner creates the file
- FileSystemWatcher detects the file, but its in use
- Scanner reads the first page to the file
- Scanner releases the file
- My code leaves the while(IsFileLocked(path))
- My code reads the incomplete file (problem)
- Scanner adds more pages to the file

假设扫描仪正在扫描 100 页,那么当“可以读取”时,文件将不完整(还剩 99 页)。

因此,有必要知道文件是否完整。可能需要等待一段时间才能查看文件是否被修改,但这个时间跨度可能长达数小时,因为扫描仪可能会空闲扫描相同的 TIF。其他解决方案是检查 TIF 文件中的一些标志,表明该文件不完整(我已经寻找过这个但没有找到任何东西)。

编辑:在这里提问之前,我已经阅读了TIFF format documentation。我发现属性 PageNumber 很有趣,但不知道它是否能解决我的问题

【问题讨论】:

  • FileInUse 函数有什么作用?
  • 您可以查询扫描仪以了解扫描完成的时间吗?
  • 它验证是否有任何程序正在读取文件,我用这种方式来保持简单,但它的作用类似于:stackoverflow.com/questions/876473/… 这个方法更好的名称是 IsFileLocked
  • SpectralGhost - 抱歉,我不能...我什至不知道是哪个扫描仪创建了该文件。我正在寻找 TIF 格式本身的解决方案,我想知道是否某些 TIF 文件头可以为我提供此信息。或者更好的是,通常设备定义的文件属性以指示文件不完整
  • 您不会在 TIFF 文件中找到显示“扫描仪尚未完成”的元数据项。您将需要更好的扫描仪或启发式或更好的扫描仪界面,例如 WIA。

标签: c# tiff filesystemwatcher scanning


【解决方案1】:

您考虑过Image.FromFile 方法吗?

如果这个函数可以打开它并读取一个有效的 tif 文件,那么你就可以了。

标题的问题是它们通常位于文件的前面并首先写入,因此文件的其余部分尚未完全写入。

您可以在文件上使用排他锁来查看扫描仪是否已完成文件写入,但这取决于扫描仪软件的行为,即它是否在写入时保持文件锁定或是否保持打开/writeblock/关闭/重复。

【讨论】:

  • 我会尽可能尝试,谢谢。但是,即使只有一页也能成功读取 Tiff 文件,对吗?
  • 这完全取决于格式,即要正确读取文件,它可能必须全部存在。我不是 100% 确定 .NET 是否可以处理多页 tiff——这似乎是您所暗示的。因此,独占文件锁定方法可能是一种替代方案;毕竟只是建议。
  • Image.FromFile 将无法检查它是否完整,因为我只能打开一页。我已经试过独占文件锁了,看看我的问题。
  • 所以扫描仪不会一直锁定文件直到完成?它打开和关闭它?如果是这样,为什么不等待 30 秒左右,如果文件在那段时间内没有改变大小,那么开始处理它。我怀疑扫描仪会打开和关闭文件并继续添加页面 - 使用页数更新过程中的标题,因此它始终是正确的。您使用的是什么扫描仪软件? - 你能改变它的行为吗?所以它在位置 X 构建文件,然后在作业完成时复制到 Y
【解决方案2】:

正如 Hans Passant 在评论中回答的那样,我发现唯一有用的解决方案是:

您不会在 TIFF 文件中找到显示“扫描仪尚未完成”的元数据项。您将需要更好的扫描仪或启发式或更好的扫描仪界面,例如 WIA。

【讨论】:

    【解决方案3】:

    您可以测试文件大小是否发生变化:

    FileInfo fi = new FileInfo(f);
    long size = fi.Length;
    Application.DoEvents();
    System.Threading.Thread.Sleep(5000);
    Application.DoEvents();
    FileInfo nfi = new FileInfo(f);
    long nsize = nfi.Length;
    if (size == nsize)
    {
        //Do function
    }
    

    【讨论】:

      猜你喜欢
      • 2011-01-25
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-07-06
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多