如何强制文件冲洗

假设我有以下代码:

#include <chrono> #include <fstream> #include <thread> int main() { std::ofstream f("test.log"); int i = 0; while (true) { f << i++; f.flush(); std::this_thread::sleep_for(std::chrono::milliseconds(100)); } } 

(请注意,每次写操作后,我都有一个flush调用)

我注意到这个应用程序不会更新“test.log”文件的“最后修改时间”和“大小”属性,除非我右键单击这个文件或打开它。

我猜这是由于内部缓冲(系统不希望将这种耗时的操作作为磁盘的实际I / O操作,除非被强制执行)。 我对吗?

我需要编写一个应用程序,以监视由其他应用程序创build的日志文件中的更改(我无法更改它们)。 起初,我想到了C#中的FileSystemWatcher类,但我注意到它具有相同的行为(除非在源应用程序中closures了文件,否则不会触发相应的事件,或者通过在Windows资源pipe理器中右键单击该文件)。 那我能做什么? 为每个我想要经常查找的文件调用WinAPI函数(如GetFileAttributes

Solutions Collecting From Web of "如何强制文件冲洗"

这里有两件独立的事情。 首先,文件MFT记录上最后一次修改的时间(相当于inode) 会在您每次写入时更新。

但是, FindFirstFile和朋友返回的信息不是来自文件,而是来自目录条目中缓存的信息。 只要关闭通过该目录条目打开的文件,就会更新此缓存。 这是大多数应用程序(如Windows资源管理器)和命令提示符DIR命令显示的信息。

如果你想知道什么时候更新了文件,你需要做一个相当于读取MFT记录(inode)的Unix stat操作。 这需要打开文件句柄,调用GetFileInformationByHandle并再次关闭句柄。

第二件事是有一个很好的理由不这样做。 如果一个程序正在写入一个文件,这可能是写作过程中的一部分。 因此该文件可能处于无效(损坏)状态。 为了确保文件处于有效状态,您应该等到文件关闭。 这就是你如何知道这个文件现在已经准备好了。

写入程序写入文件后,目录条目将被更新,FileSystemWatcher将显示该文件。

如果您确定要查看仍在编写文件的通知,则可以查看USN更改日志作为选项。 我不知道这是否保持比目录条目更新,你将不得不调查。