.net 如何确保所有数据都已物理写入磁盘?

j13ufse2  于 2023-01-18  发布在  .NET
关注(0)|答案(7)|浏览(152)

我知道.NET FileStream的Flush方法只将当前缓冲区写入磁盘,但根据Windows的磁盘驱动程序和硬盘固件,这不能保证数据实际上物理写入磁盘。
是否有.NET或Win32方法可以给予我这样的保证?这样,如果在调用此方法返回后一纳秒断电,我仍然可以确定一切正常?

vjhs03f7

vjhs03f71#

斯特凡·S说:
我知道.NET FileStream的Flush方法只将当前缓冲区写入磁盘
不,.NET FileStream的Flush只将.NET缓冲区写入操作系统缓存,它不会将操作系统缓存刷新到磁盘。遗憾的是,关于此类的MSDN文档没有这样说。对于.NET〈4.0,您必须调用Flush + Win32的FlushFilebuffers:

using System.Runtime.InteropServices;
. . .

// start of class:
[DllImport("kernel32", SetLastError=true)]
private static extern bool FlushFileBuffers(IntPtr handle);
. . .

stream.Flush();     // Flush .NET buffers to OS file cache.
#pragma warning disable 618,612 // disable stream.Handle deprecation warning.
if (!FlushFileBuffers(stream.Handle))   // Flush OS file cache to disk.
#pragma warning restore 618,612
{
  Int32 err = Marshal.GetLastWin32Error();
  throw new Win32Exception(err, "Win32 FlushFileBuffers returned error for " + stream.Name);
}

对于.NET 4.0,您可以改用新的flush(true)方法。11/09/2012更新:微软的错误报告说它坏了,然后修复了,但没有说它是在什么版本或服务包中修复的!听起来像是错误,如果内部.NET FileStream缓冲区是空的,刷新(真)什么也没做?

umuewwlo

umuewwlo2#

在Windows下,查看FlushFileBuffers(Win32 API)。

goqiplq2

goqiplq23#

好吧,你可以关闭文件.... a.这很可能就可以了。实际上,随着HAL抽象化、虚拟化和磁盘硬件现在比几年前的 * 计算机 * 拥有更强的处理能力和缓存内存,你将不得不希望磁盘完成它的工作。
事务性文件系统从未真正实现;-p当然,您也许可以考虑使用数据库作为后端,并使用它的事务系统。
旁白:注意,并不是所有的流都能保证Flush()--例如,GZipStream等即使在刷新之后也会保留一个未提交数据的工作缓冲区--让它刷新 * 所有内容 * 的唯一方法是Close()它。

gdrx4gfi

gdrx4gfi4#

我注意到.NET 4 #Flush(true)实际上并不写入磁盘。我们遇到了数据损坏的奇怪问题,我在MS网站上找到了这个bug报告:
错误报告的详细信息选项卡有一个测试程序,您可以运行它来显示问题;
1.将一堆数据写入磁盘

  1. fs.Flush(true)。这不需要时间(比可能写入磁盘的速度快得多)。
    1.使用win32 API FlushFileBuffers。这需要很长时间。
    我正在切换到win32 FlushFileBuffers调用...
yr9zkbsy

yr9zkbsy5#

将缓冲区的内容刷新到磁盘有一个简单的答案。在WriteAllText函数之后,打开文件,关闭它,然后重置它
下面是一个示例

My.Computer.FileSystem.WriteAllText(yourfilename, "hello", False, System.Text.Encoding.ASCII)
FileOpen(1, yourfilename, OpenMode.Input)
FileClose(1)
Reset()
zbq4xfa0

zbq4xfa06#

缓存在文件系统缓存中并要写入磁盘的文件数据。根据磁盘写入磁头的位置,这些数据通常是延迟写入的。缓存1 GB的数据在技术上是可行的,因此可能需要相当长的时间。如果这对您很重要,则考虑FileOptions.WriteThrough选项。

8cdiaqws

8cdiaqws7#

有太多的抽象层次,以至于无法绝对确定数据是否被写入磁盘,一直到硬件层次。
性能不是很好,也不是很简单,但是如果文件是在一个单独的进程中编写的,那么重新打开它并检查大小或内容怎么样?

相关问题