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

How to get correct file size only on the completion of a detected file change, not at the beginning?

我正在使用 libuv 的 uv_fs_event_t 来监视文件更改。一旦检测到更改,我就会在回调 uv_fs_event_cb.

中打开文件

但是,我的程序在打开文件时还需要获取完整的文件大小,所以我会根据文件大小知道要分配多少内存。我发现无论我使用 libuv 的 uv_fs_fstat 或 POSIX 的 stat/stat64,还是 fseek+ftell 我都无法立即获得正确的文件大小。这是因为当我的程序打开文件时,文件还在更新中。

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

有没有办法在利用或不利用 libuv 的情况下处理这个问题,这样我就可以,比如推迟打开和读取文件,直到文件写入完成?换句话说,我不是立即检测文件更改事件的开始,而是可以通过某种方式检测文件更改的 完成 吗?

一种方法是让作者创建一个中间文件,然后通过将其重命名为目标文件来完成 I/O。例如这是大多数浏览器中发生的情况,该文件在下载完成之前具有“downloading.tmp”名称,以阻止您打开它。

另一种方法是在写入主要目标文件后 write/touch 一个“完成”文件,并在 reader 开始他的工作之前等待查看该文件。

我能看到的最后一个选项,如果可以稍微改变文件格式,让编写器将文件大小打印为文件的第一个字节,那么即使文件不是,reader 也可以正确预分配完全写入,然后会坚持读取所有数据。

总的来说,我建议不要使用 完成事件 ,让编写器在完成任务后生成任何可以监视的事件,并让 reader wait/synchronize 在那个事件上。