2008-10-06 143 views
4

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

我想在C++中以编程方式执行此操作。

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

+0

你的意思是编程?这个问题没有说清楚 – 2008-10-06 08:16:19

+0

我们假设你的问题是关于编程,但是你没有指定开发环境。 – tzot 2008-10-06 08:41:29

回答

2

您还没有指定的发展环境,因此:

IO流有一个.Flush方法你想要做什么。

的Win32 API

还有就是FlushFileBuffers呼叫,这需要一个文件句柄作为参数。

编辑(基于来自OA的评论):FlushFileBuffers不需要管理权限;它只有在传递给它的句柄是一个卷的句柄而不是单个文件的时候。

+0

看来,这将工作。不幸的是,应用程序必须能够运行而不需要管理权限。 – selwyn 2008-10-06 11:24:08

+0

我找不到这个.NET方法。据我所见,框架使用FlushFileBuffers的唯一地方是在SerialStream中。我怀疑p /调用FlushFileBuffers是安全的。 – 2009-03-25 23:08:00

1

从微软文档你可以使用_flushall和COMMODE.OBJ链接来确保所有的缓冲区都被提交到磁盘。

2

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

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

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

3

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

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

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

另请参阅MSDN上的file bufferingfile caching

8

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