我需要创建一个新的文件句柄,以便对该句柄的任何写操作立即写入磁盘。
额外信息:句柄将是子进程继承的 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
标志,出于同样的原因,我不能使用它 - 无法控制使用句柄的进程,因此我无法按照该标志的要求手动对齐写入。
编辑:我做了一个单独的项目,专门用于观察文件大小的变化。它使用 .NETFileSystemWatcher
类。我也写了更少的数据——总共大约 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.
...和“强制(手动)刷新”版本(FlushFileBuffers()
每约 2.5 秒调用一次):
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.