【问题标题】:How to detect when a folder change is completed? [duplicate]如何检测文件夹更改何时完成? [复制]
【发布时间】:2020-10-14 01:40:11
【问题描述】:

我正在使用 Delphi 和 ReadDirectoryChangesW(在 TThread 中)来检测特定文件夹何时发生更改。这工作得很好。我需要知道更改何时完成,以便我可以安全地对文件进行操作。

以下是场景:我已将打印机映射到特定的文件名和文件夹(文件:本地端口c:\MonitorMe\prinfil.dat)。文件夹中的唯一文件将是该打印机文件。打印作业可以是单页,也可以是数百页——我必须等到“打印到文件”完成后才能触发进一步的操作。我正在监视 FILE_NOTIFY_CHANGE_SIZEFILE_NOTIFY_CHANGE_LAST_WRITE - 所以我会定期收到文件仍在“打印到”的通知。

我正在寻找一种安全的方法来实际检测“打印”何时完成。我想我可以在表单中设置一个计时器,并在线程中调用Synchronize(StillPrinting)StillPrinting 将停止并重新启动计时器,这样只有在大约 300 毫秒的 NO 文件夹更改后,计时器才会执行 - 触发 OnAfterPrintComplete 事件。这似乎很危险。

我可以通过什么来确定文件保存是否已完成?

【问题讨论】:

  • @fpiette 事实上,就是这样——当我阅读 FILE_NOTIFY_CHANGE_LAST_WRITE 标志的 ms 文档时,我将其解释为“每次写入”(上次写入时,每次保存多次写入)。它实际上意味着“文件关闭时最后一次写入”——这正是我想要的。我保存了一个 1300 页的文件,它完成了我需要的操作。谢谢。

标签: delphi tthread readdirectorychangesw


【解决方案1】:

“文件已完成”是主观的 - 只需考虑 5 分钟,您就会得出结论:您所要求的东西很少有意义:

  • 写入速度可能会有所不同:您可能希望文件在一个系统上写入 2 秒,而在另一个系统上则需要 5 分钟。
  • 画线:您认为何时完成“写入”以及其他写入附加到现有文件的时间?关于可能需要 2 年才能再次写入该文件的日志。同样,无论出于何种原因,您的打印机作业/程序可能会闲置 10 分钟,但仍可以访问该文件。
  • 修改:如果文件从字节 1 写入到 52000,但之后字节 10 到 19 被覆盖,该怎么办?什么时候认为“完成”?
  • 即使SetEndOfFile() 仅在给定点“剪切”(或扩展)文件,但没有人知道是否会在任何位置发生额外的写入。

没有。但是有多种方法可以实现相同的目标:

  • 设置文件属性,即R 可能表示不会再发生写入。因为您作为消费者无论如何都只想要读取权限。当然,“打印机”必须设置它。
  • 检查文件内容是否有有效的页脚,或者其格式是否不完整。这都需要您知道打印文件格式和打印文件完全有格式(而不仅仅是二进制流)。
  • 试图打开文件没有任何共享权限(甚至FILE_SHARE_READ) - 只要另一个进程访问该文件,这应该会失败。您可以预期打印机作业不会多次打开/关闭文件(尽管也有可能)。
  • 滥用文件作为“写入完成”标记:如果文件已被写入,则创建另一个(空)文件,其单独存在表示另一个文件已完成。根据您的打印作业/程序,您可以添加另一个简短/简单的打印任务,并判断只要存在 2 个文件,就必须完成一个感兴趣的文件(而另一个与您无关)。

【讨论】:

  • 感谢 cmets - 在这种特殊情况下,只有一个进程写入该特定文件。这是一个打印运输标签的程序 - 我希望用我自己的格式替换内置标签格式(我可以确定要从 sql 查询中打印的实际数据)。除了打印文件之外,我什么都没有 - 我在想也许可以使用 FindFirstChangeNotificationW - 当我看到打印文件发生变化时,然后每 200 毫秒循环一次,检查是否可以打开文件。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2013-09-11
  • 1970-01-01
  • 1970-01-01
  • 2011-11-14
  • 2018-04-09
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多