问题描述
我正在使用Delphi和ReadDirectoryChangesW
(在TThread
中)来检测特定文件夹的更改时间。这工作得很好。我需要知道何时完成更改 ,这样我才能安全地对文件进行操作。
在这种情况下:我已将打印机映射到特定的文件名和文件夹(FILE:本地端口c:\MonitorMe\prinfil.dat
)。文件夹中的唯一文件将是该打印机文件。打印作业可以是一页,也可以是数百页-我必须等到“打印到文件”完成后才能触发进一步的操作。我正在监视FILE_NOTIFY_CHANGE_SIZE
和FILE_NOTIFY_CHANGE_LAST_WRITE
-因此,我会定期收到有关文件仍“正在打印到”的通知。
我正在寻找一种安全的方法来实际检测“打印”完成的时间。我以为我可以在表单中设置一个计时器,然后在线程中调用Synchronize(StillPrinting)
。 StillPrinting
将停止并重新启动计时器,以便仅在大约300毫秒的NO文件夹更改后,计时器才会执行-触发OnAfterPrintComplete
事件。那似乎很危险。
我可以寻找什么来确定文件保存是否完成吗?
解决方法
“文件已完成”是主观的-考虑5分钟,您将得出结论,要求的东西很少有意义:
- 写入速度可能有所不同:您可能希望在一个系统上以2秒的时间写入文件,而在另一个系统上则需要5分钟。
- 划清界限:在什么时候您认为“写”操作已完成,并且在其他时候追加到现有文件的其他写操作?关于可能需要2年才能再次写入该文件的日志。同样,无论出于何种原因,您的打印机作业/程序都可以闲置10分钟,但仍然可以访问文件。
- 修改:从字节1到52000写入但之后字节10到19被覆盖的文件怎么办?那什么时候才算“完成”?
- 即使SetEndOfFile()仅在给定的位置“剪切”(或扩展)文件,但没有人知道是否会在任何位置进行额外的写入。
不。但是有多种方法可以实现相同的目标:
- 设置文件属性,即
R
可能表示不再发生写入操作。因为您作为消费者只想读取访问权限。当然,“打印机”必须进行设置。 - 检查文件内容中的有效页脚,或者其格式似乎不完整。这两者都需要您了解打印文件格式,并且完全知道打印文件具有某种格式(而不只是二进制流)。
- 尝试没有任何共享权限(甚至没有
FILE_SHARE_READ
)打开文件-只要另一个进程访问该文件,此操作就会失败。您可以期望打印机作业不会多次打开/关闭文件(尽管也有可能)。 - 将文件滥用为“写入完成”标记:如果文件已被写入,则创建另一个(空)文件,其单独存在表示另一个文件已完成。根据您的打印作业/程序,您可以添加另一个简短的打印任务,并判断只要存在两个文件,就必须完成一个感兴趣的文件(而另一个与您无关)。