windows 刷新磁盘写入缓存

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/173560/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-15 11:23:52  来源:igfitidea点击:

Flush disk write cache

windowswindows-xpdisk

提问by selwyn

When the policy for a disk in Windows XP and Vista is set to enable write caching on the hard disk, is there a way to flush a file that has just been written, and ensure that it has been committed to disk?

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

I want to do this programmatically in C++.

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

Closing the file does perform a flush at the application level, but not at the operating system level. If the power is removed from the PC after closing the file, but before the operating system has flushed the disk write cache, the file is lost, even though it was closed.

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

采纳答案by tzot

You haven't specified the development environment, so:

你还没有指定开发环境,所以:

.Net

。网

IO streams have a .Flushmethod that does what you want.

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

Win32 API

Win32 API

There is the FlushFileBufferscall, which takes a file handle as argument.

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

EDIT (based on a comment from the OA): FlushFileBuffers does not need administrative privileges; it does only if the handle passed to it is the handle for a volume, not for a single file.

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

回答by jimvfr

.NET FileStream.Flush() will NOT flush the Windows cache for that file content; Flush() only flushes the .NET internal file buffer. In .NET 4.0, Microsoft fixed the problem by adding an optional parameter to Flush() which if set true causes FlushFileSystemBuffers to be called. In .NET 3.5 and below your only choice is to call FlushFileBuffers via pinvoke. See MSDN'sFileStream.Flushcommunity comment for how to do this.

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

回答by MSalters

You should not fix this at the time you close the file. Windows will cache, unless you open the file passing FILE_FLAG_WRITE_THROUGHto CreateFile().

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

You may also want to pass FILE_FLAG_NO_BUFFERING; this tells Windows not to keep a copy of the bytes in cache.

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

This is more efficient than FlushFileBuffers(), according to the CreateFile documentation on MSDN.

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

See also file bufferingand file cachingon MSDN.

另请参阅MSDN 上的文件缓冲文件缓存

回答by Philipp

You should also note, that your data might not get flushed to the actualdisk, even when invoking a flush method of your frameworks API.

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

Calling the flush method will only tell the kernel to flush its pages to disk. However, if you have the disk write-cache turned on, it is allowed to delay the actual writing process indefinitely.

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

In order to ensure that your data gets written to the physical layer you have to turn of the write cache in your operating system. This most often comes with a performance penalty up to one or two orders of magnitude when dealing with a lot of small io-operations. Battery based support (UPS) or disks that accept commands to flush the disk write-cache are another option to deal with this problem.

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

回答by SmacL

From the microsoft documents you would use _flushalland link in COMMODE.OBJ to ensure that all buffers were committed to disk.

从微软文档中,您将使用_flushallCOMMODE.OBJ 中的链接来确保所有缓冲区都提交到磁盘。

回答by Artie Leech

See here: https://jeffpar.github.io/kbarchive/kb/066/Q66052/

见这里:https: //jeffpar.github.io/kbararchive/kb/066/Q66052/

When you initially open your file using fopen, include the "c" mode option as the LAST OPTION:

当您最初使用 fopen 打开您的文件时,包括“c”模式选项作为最后一个选项:

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

Then when you want to force a flush to disk, call

然后当你想强制刷新到磁盘时,调用

_flushall()

We made this call before calling

我们在打电话之前打了这个电话

fclose()

We experienced the exact issue you described and this approach fixed it.

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

Note that this approach does NOT required Administrative rights, which FlushFileBuffersdoesrequire, as others have mentioned.

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

From that above site:

从上面的网站:

"Microsoft C/C++ version 7.0 introduces the "c" mode option for the fopen() function. When an application opens a file and specifies the "c" mode, the run-time library writes the contents of the file buffer to disk when the application calls the fflush() or _flushall() function. "

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