【发布时间】:2008-11-25 15:54:24
【问题描述】:
我需要创建一个新的文件句柄,以便对该句柄的任何写操作立即写入磁盘。
额外信息:句柄将是子进程继承的 STDOUT,因此我需要将该进程的任何输出立即写入磁盘。
研究CreateFile 文档,FILE_FLAG_WRITE_THROUGH 标志看起来正是我所需要的:
写操作不会通过 任何中间缓存,他们都会去 直接写入磁盘。
我编写了一个非常基本的测试程序,但是它不起作用。
我在 CreateFile 上使用了标志,然后在一个长循环中使用了WriteFile(myHandle,...),在大约 15 秒内写入了大约 100MB 的数据。 (我添加了一些Sleep()'s)。
然后我设置了一个专业的监控环境,包括在资源管理器中连续按“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.
...和“强制(手动)刷新”版本(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.
【问题讨论】:
-
你认为你为什么需要这个?
-
+1 表示
professional Explorer + F5。但我必须提醒您,同一操作系统内的可见性并不意味着flushing/durability。您必须采取更专业的行动:重置 PC 或从系统中热提取 HDD。我不确定重置或关机不会启动板载缓存刷新。只有当您物理移除驱动器或使用一些假存储时,您才能确定刷新确实到达了设备。 -
@RecognizeEvilasWaste 嗯...让我们看看它是否有效