5

我正在开发一个与名为 Dazzle 的 USPS 运输包接口的系统。该系统的一部分包括一个监控守护进程,其目的是获取制表符分隔的值文件,将它们转换为 Dazzle 识别的 XML,并将它们传递给 Dazzle 以生成标签。这部分工作得很好。然而,我还想做的是解析 Dazzle 生成的输出文件并将其导入数据库。

请注意,Dazzle 在 Windows 上运行。我的监控守护程序是用 Perl 编写的,并在 Linux 上运行。我的 Linux 系统通过 Samba 挂载了 Dazzle 的输入和输出目录。

Dazzle 开始写入输出文件的时间和它完成的时间之间有一个可测量的延迟。我想知道的是如何等待 Dazzle 完成输出文件的写入?我试过打开文件并对其进行flock($fh, LOCK_SH)操作,但这似乎没有任何好处。

编辑:我有一个基于下面“mobrule”评论的想法。Dazzle 以 XML 格式编写输出文件。货件中的每个包裹都附在标签中,整个文件都附在标签中。因此,如果我在文件完成之前开始阅读文件,我可以在采取行动之前等待适当的结束标记。

另外,我应该提到我目前正在做的事情。当我检测到输出 XML 文件已创建时,我尝试对其进行解析。如果解析失败,我会睡觉并重试。如果失败,我会睡两倍的时间,然后再试一次,依此类推。这在 64 秒超时的测试中效果很好。

4

4 回答 4

5

没有通用且可移植的方法来判断某个进程是否具有某个任意文件的打开文件句柄。您必须根据当地情况做出判断。

在这种情况下,可以查询Windows机器上的进程表,看看“Dazzle”程序是否还在运行。或者您的经验可能会为您提供其他指导,例如“当输入合理时,Dazzle 的运行时间不会超过 20 秒”或“当 Dazzle 运行时,它会每隔几秒钟更新一个文件。如果文件尚未更新比如说,在 10 秒内,Dazzle 很有可能会完成。”

但您不一定要等到 Dazzle 完成。在 Dazzle 写入文件的同时读取文件是完全可以的——查看函数的 perldocseek,注意关于“如何模拟tail -f”的部分。然后您可以在 Dazzle 运行时更新您的数据库。

这样,如果您过于保守地猜测 Dazzle 何时完成,您的数据库仍然会及时更新,唯一的代价将是在 EOF 处对文件句柄进行一些无用的查找和读取调用。

于 2010-02-25T16:12:27.893 回答
1

这可能不是一个很好的解决方案,但是您可以尝试反复重命名文件,如果失败则休眠一会儿。

于 2010-02-25T15:40:12.737 回答
1

您可以尝试使用 LOCK_EX 进行锁定 - 如果锁定失败,则意味着它仍在被写入。像这样旋转直到你获得锁,并且应该完成炫目。如果 Dazzle 曾经关闭文件并以附加模式再次打开它,这将失败,因此这不是最佳解决方案。

于 2010-02-25T15:40:50.393 回答
1

也许您可以让 Dazzle 写出一个虚拟文件或标志文件(它可以包含您想要的任何内容,例如日期/时间戳或序列号)以表明 Dazzle 已完成文件的写入。然后你所做的就是测试这个文件的存在以知道它已经完成了。

于 2010-02-25T15:45:25.190 回答