如何仅在检测到文件更改完成时而不是在开始时获取正确的文件大小?

问题描述

我正在使用libuv的uv_fs_event_t监视文件更改。并且一旦检测到更改,便在回调uv_fs_event_cb中打开文件

但是,我的程序在打开文件时也需要获得完整的文件大小,因此我将根据文件大小知道要分配多少内存。我发现无论我使用libuv的uv_fs_fstat还是POSIX的stat/stat64fseek+ftell我都永远不会立即获得正确的文件大小。这是因为当我的程序打开文件时,文件仍在更新中。

我的程序在带有回调的紧密单线程中运行,因此延迟/睡眠不是这里的最佳选择(也不能保证正确性)。

有没有办法使用或不使用libuv来处理此问题,比如说我可以推迟打开和读取文件,直到写入文件完成为止?换句话说,不是立即检测到文件更改开始,而是可以某种方式检测到文件更改的完成

解决方法

一种方法是让编写器创建一个中间文件,并通过将其重命名为目标文件来完成I / O。例如这是在大多数浏览器中都会发生的情况,该文件的名称为“ downloading.tmp”,直到下载完成后才阻止您打开它。

另一种方法是在写入主要目标文件后写入/触摸“完成”的文件,然后在阅读器开始工作之前等待查看该文件。

最后一个选项,我可以看到,如果可以稍稍更改文件格式,请编写者将文件大小打印为文件的第一个字节,那么即使文件未完全写入,读者也可以正确地对其进行预分配,然后将坚持读取所有数据。

总体上,我建议您不要编写完成事件,而是让编写器在完成任务后生成任何可以监视的事件,并让读者等待/同步该事件。