我需要创建一个新的文件句柄,以便对该句柄的任何写操作都可以立即写入磁盘。
额外信息:句柄将是子进程的继承STDOUT,因此我需要该进程的任何输出立即写入磁盘。
在研究CreateFile
文档时,FILE_FLAG_WRITE_THROUGH
标志看起来完全像我所需要的:
我写了一个非常基本的测试程序,但是,它没有用。
我在CreateFile上使用了该标志,然后在很长的循环中使用了WriteFile(myHandle,...)
,在大约15秒内写入了大约100MB的数据。 (我添加了一些Sleep()
)。
然后,我建立了一个专业的监视环境,其中包括在资源管理器中连续命中“F5”。结果:文件停留在0kB,然后在测试程序结束时跳至100MB。
我尝试的下一件事是在每次写入后使用FlushFileBuffers(myHandle)
手动刷新文件。如预期的那样,这使观察到的文件大小变得稳定且稳定。
我的问题是,如果没有手动刷新文件,那么FILE_FLAG_WRITE_THROUGH
是否应该完成此?我想念什么吗?
在“现实世界”程序中,我无法刷新文件,因为我无法控制正在使用该文件的子进程。
还有FILE_FLAG_NO_BUFFERING
标志,出于相同的原因,我无法使用它-无法控制使用句柄的进程,因此我无法根据此标志的要求手动对齐写入。
编辑:
我专门制作了一个单独的项目,用于观察文件大小如何变化。它使用.NET FileSystemWatcher
类。我也写更少的数据-总共大约100kB。
这是输出。查看时间戳记中的秒数。
“内置的无缓冲区”版本:25.11.2008 7:03:22 PM: 10230 bytes added.
25.11.2008 7:03:31 PM: 10240 bytes added.
25.11.2008 7:03:31 PM: 10240 bytes added.
25.11.2008 7:03:31 PM: 10240 bytes added.
25.11.2008 7:03:31 PM: 10200 bytes added.
25.11.2008 7:03:42 PM: 10240 bytes added.
25.11.2008 7:03:42 PM: 10240 bytes added.
25.11.2008 7:03:42 PM: 10240 bytes added.
25.11.2008 7:03:42 PM: 10240 bytes added.
25.11.2008 7:03:42 PM: 10190 bytes added.
...以及“强制(手动)冲洗”版本(每〜2.5秒调用一次FlushFileBuffers()
):25.11.2008 7:06:10 PM: 10230 bytes added.
25.11.2008 7:06:12 PM: 10230 bytes added.
25.11.2008 7:06:15 PM: 10230 bytes added.
25.11.2008 7:06:17 PM: 10230 bytes added.
25.11.2008 7:06:19 PM: 10230 bytes added.
25.11.2008 7:06:21 PM: 10230 bytes added.
25.11.2008 7:06:23 PM: 10230 bytes added.
25.11.2008 7:06:25 PM: 10230 bytes added.
25.11.2008 7:06:27 PM: 10230 bytes added.
25.11.2008 7:06:29 PM: 10230 bytes added.
最佳答案
在崩溃日志记录的背景下,我也为此感到痛苦。FILE_FLAG_WRITE_THROUGH
仅保证在WriteFile
返回之前,您要发送的数据已发送到文件系统。它不能保证它实际上已发送到物理设备。因此,例如,如果在带有此标志的句柄上的ReadFile
之后执行WriteFile
,则可以确保读取操作将返回您写入的字节,无论它是从文件系统缓存还是从底层设备获取数据。
如果要保证已将数据写入设备,则需要FILE_FLAG_NO_BUFFERING
,并伴随所有额外的工作。例如,这些写入必须对齐,因为缓冲区在返回之前一直向下到达设备驱动程序。
知识库在区别上有一个terse but informative article。
在您的情况下,如果父进程要比 child 长寿,那么您可以:
CreatePipe
API创建可继承的匿名管道。 CreateFile
创建一个设置了FILE_FLAG_NO_BUFFERING
的文件。 关于winapi - Win32 : Write to file without buffering?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/317801/