当Windows XP和Vista中的磁盘策略设置为在硬盘上启用写入缓存时,是否有办法刷新刚刚写入的文件,并确保它已提交到磁盘?< / p>
我想用C ++编程。
关闭文件会在应用程序级别执行刷新,但不会在操作系统级别执行。如果在关闭文件后但在操作系统刷新磁盘写入缓存之前从PC中断电,则文件将丢失,即使它已关闭。
答案 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 buffering和file caching。
答案 2 :(得分:2)
您尚未指定开发环境,因此:
IO流有一个.Flush
方法可以满足您的需要。
有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()函数。 “