我正在开发一个与名为Dazzle的USPS运输包接口的系统。该系统的一部分包括一个监视守护进程,其目的是获取制表符分隔的值文件,将它们转换为Dazzle识别的XML,并将它们传递给Dazzle以生成标签。这部分工作得很好。但是,我还想要解析Dazzle生成的输出文件并将其导入数据库。
请注意Dazzle在Windows上运行。我的监控守护进程是用Perl编写的,可以在Linux上运行。我的Linux系统通过Samba安装了Dazzle的输入和输出目录。
Dazzle开始写入输出文件的时间和完成的时间之间存在可测量的延迟。我想知道的是我如何等待Dazzle完成输出文件的编写?我已经尝试打开文件并在其上执行flock($fh, LOCK_SH)
,但这似乎没有任何好处。
编辑:我有一个基于“mobrule”评论的想法。 Dazzle用XML编写输出文件。货件中的每个包装都包含在标签中,整个文件都包含在标签中。所以,如果我在文件完成之前就开始阅读文件,我可以在采取行动之前等待合适的结束标记。
另外,我应该提一下我目前在做什么。当我检测到已创建输出XML文件时,我尝试解析它。如果解析失败,我会睡觉并再试一次。如果失败了,我会睡两次,然后再试一次,依此类推。这在64秒的超时测试中运行良好。
答案 0 :(得分:5)
没有通用和可移植的方法来判断某个进程是否有某个任意文件的打开文件句柄。你必须根据当地的情况做出判断。
在这种情况下,可以在Windows机器上查询进程表,以查看“Dazzle”程序是否仍在运行。或者,您的经验可能会为您提供其他指导,例如“当输入合理时,Dazzle永远不会超过20秒运行”或“Dazzle运行时,它会每隔几秒更新一次文件。如果文件尚未更新比方说,10秒,那么Dazzle很有可能完成。“
但是你不一定要等到Dazzle结束。在Dazzle写信的同时阅读文件是完全可以的 - 请参阅the perldoc for the seek
function,注意关于“如何模仿tail -f
”的部分。然后,您可以在Dazzle运行时更新数据库。
这样一来,如果你对Dazzle完成时的猜测过于保守,你的数据库仍然会及时更新,唯一的代价是在EOF文件句柄上进行一些无用的搜索和读取调用。
答案 1 :(得分:1)
这可能不是一个很好的解决方案,但您可以尝试重复重命名该文件,如果失败则请稍微休眠一下。
答案 2 :(得分:1)
您可以尝试使用LOCK_EX进行锁定 - 如果锁定失败,则意味着它仍在被写入。这样旋转直到你获得锁定,并且应该完成炫目。如果Dazzle关闭文件并再次打开附加模式,这将失败,因此它不是最好的解决方案。
答案 3 :(得分:1)
也许你可以让Dazzle写出一个虚拟或标记文件(它可以包含你想要的任何东西,如日期/时间戳或序列号)来表示Dazzle已经完成了文件的写入。然后你要做的就是测试这个文件的存在,以确定它已经完成。