刷新磁盘写缓存

时间:2008-10-06 08:12:49

标签: windows windows-xp disk

当Windows XP和Vista中的磁盘策略设置为在硬盘上启用写入缓存时,是否有办法刷新刚刚写入的文件,并确保它已提交到磁盘?< / p>

我想用C ++编程。

关闭文件会在应用程序级别执行刷新,但不会在操作系统级别执行。如果在关闭文件后但在操作系统刷新磁盘写入缓存之前从PC中断电,则文件将丢失,即使它已关闭。

6 个答案:

答案 0 :(得分:8)

.NET FileStream.Flush()不会刷新该文件内容的Windows缓存; Flush()仅刷新.NET内部文件缓冲区。在.NET 4.0中,Microsoft通过向Flush()添加可选参数来解决此问题,如果设置为true,则会调用FlushFileSystemBuffers。在.NET 3.5及更低版本中,您唯一的选择是通过pinvoke调用FlushFileBuffers。有关如何执行此操作,请参阅MSDN的FileStream.Flush社区评论。

答案 1 :(得分:4)

您不应在关闭文件时修复此问题。 Windows将缓存,除非您打开通过FILE_FLAG_WRITE_THROUGH到CreateFile()的文件。

您可能还想传递FILE_FLAG_NO_BUFFERING;这告诉Windows不要在缓存中保留字节的副本。

根据MSDN上的CreateFile文档,这比FlushFileBuffers()更有效。

另请参阅MSDN上的file bufferingfile caching

答案 2 :(得分:2)

您尚未指定开发环境,因此:

的.Net

IO流有一个.Flush方法可以满足您的需要。

Win32 API

FlushFileBuffers调用,它将文件句柄作为参数。

EDIT(基于来自OA的评论):FlushFileBuffers不需要管理权限;仅当传递给它的句柄是卷的句柄而不是单个文件时才会这样做。

答案 3 :(得分:2)

您还应该注意,即使在调用框架API的flush方法时,您的数据也可能无法刷新到实际磁盘。

调用flush方法只会告诉内核将其页面刷新到磁盘。但是,如果您打开了磁盘写入缓存,则可以无限期地延迟实际写入过程。

为了确保将数据写入物理层,您必须在操作系统中关闭写入缓存。在处理大量小型io操作时,这通常会带来高达一到两个数量级的性能损失。 基于电池的支持(UPS)或接受命令来刷新磁盘写缓存的磁盘是处理此问题的另一种选择。

答案 4 :(得分:1)

从microsoft文档中,您将使用_flushall并在COMMODE.OBJ中链接以确保所有缓冲区都已提交到磁盘。

答案 5 :(得分:0)

参见此处:https://jeffpar.github.io/kbarchive/kb/066/Q66052/

最初使用fopen打开文件时,请在最后一个选项中加入“ c”模式选项:

fopen( path, "wc") // w - write mode, c - allow immediate commit to disk

然后,当您要强制刷新到磁盘时,调用

_flushall()

我们在致电

之前先打了这个电话
fclose()

我们遇到了您所描述的确切问题,并且此方法已将其解决。

请注意,这种方法不需要管理权限,正如其他人提到的那样,FlushFileBuffers 要求。

从上述网站上

“ Microsoft C / C ++ 7.0版为fopen()引入了” c“模式选项 功能。当应用程序打开文件并指定“ c”模式时, 当运行库将文件缓冲区的内容写入磁盘时, 应用程序调用fflush()或_flushall()函数。 “