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

发布于 2024-07-11 19:15:46 字数 169 浏览 8 评论 0原文

据我了解,.NET FileStream 的 Flush 方法仅将当前缓冲区写入磁盘,但依赖于 Windows 的磁盘驱动程序和硬盘固件,这不能保证数据实际上物理写入磁盘。

有没有 .NET 或 Win32 方法可以给我这样的保证? 因此,如果在调用此方法返回后一纳秒断电,我仍然可以确定一切正常吗?

I understand that .NET FileStream's Flush method only writes the current buffer to disk, but dependent on Windows' disk driver and the hard disk firmware this is no guarantee that the data is actually physically written to disk.

Is there a .NET or Win32 method that can give me this guarantee? So if there is power loss one nanosecond after the call to this method comes back, I can still be sure that everything is OK?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(7

甜味拾荒者 2024-07-18 19:15:46

斯特凡·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,您可以使用新的 flash(true) 方法。
2012 年 11 月 9 日更新:MS 错误报告 这里 说它已损坏,然后修复,但没有说明修复的版本或服务包! 听起来好像 bug 是如果内部 .NET FileStream 缓冲区为空,则 Flush(true) 不会执行任何操作?

Stefan S. said:

I understand that .NET FileStream's Flush method only writes the current buffer to disk

No, .NET FileStream's Flush only writes the .NET buffers to the OS cache, it does not flush the OS cache to disk. Sadly the MSDN doc on this class doesn't say that. For .NET < 4.0, you'll have to call Flush + Win32's 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);
}

For .NET 4.0, you can instead use the new flush(true) method.
11/09/2012 update: MS bug report here says it's broken, then fixed, but doesn't say what version or service pack it was fixed in! Sounds like bug was if internal .NET FileStream buffer is empty, the Flush(true) did nothing??

︶ ̄淡然 2024-07-18 19:15:46

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

Under Windows, look at FlushFileBuffers (Win32 API).

稚然 2024-07-18 19:15:46

好吧,你可以关闭该文件......这可能会做到这一点。 事实上,随着 HAL 抽象、虚拟化和磁盘硬件现在比几年前的计算机拥有更多的处理能力和缓存,您将不得不忍受希望磁盘完成其工作的希望。

事务性文件系统从未真正实现;-p 当然,您也许可以考虑使用数据库作为后端,并使用其事务系统?

另外:请注意,并非所有流都保证 Flush() - 例如,GZipStream 等即使在刷新之后也会保留未提交数据的工作缓冲区 - 这是获得的唯一方法要刷新一切就是Close()它。

Well, you could close the file... that would probably do it. In reality, with HAL abstraction, virtualization, and disk hardware now having more processing power and cache memory than computers did a few years ago, you're going to have to live with hoping the disk does its job.

The transactional file system never really materialized ;-p Of course, you could perhaps look at using a database as a back end, and use the transaction system of that?

Aside: note that not all streams even guarantee to Flush() - for example, GZipStream etc retain a working buffer of uncommitted data even after a flush - the only way to get it to flush everything is to Close() it.

ま昔日黯然 2024-07-18 19:15:46

我注意到 .NET 4 #Flush(true) 实际上并没有写入磁盘。 我们遇到了数据损坏的奇怪问题,我发现了这个 错误报告

错误报告的详细信息选项卡有一个测试程序,您可以运行该程序来显示问题;

  1. 将一堆数据写入磁盘
  2. fs.Flush(true)。 这不需要时间(比写入磁盘的速度快得多)。
  3. 使用 win32 API FlushFileBuffers。 这需要很长时间。

我正在切换到 win32 FlushFileBuffers 调用...

I've noticed that the .NET 4 #Flush(true) doesn't actually write to the disk. We were having strange issues with corrupted data and I found this bug report on the MS site:

The details tab for the bug report has a test program you can run that will show the issue;

  1. Write a bunch of data to disk
  2. fs.Flush(true). This takes no time (much faster than can possibly written to the disk).
  3. Use the win32 API FlushFileBuffers. This takes a long time.

I'm changing over to the win32 FlushFileBuffers call...

可爱咩 2024-07-18 19:15:46

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

这是一个例子

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

There is a simple answer to flushing the content of the buffer to disk.
After your WriteAllText function, open file, close it, and reset it

here is an example

My.Computer.FileSystem.WriteAllText(yourfilename, "hello", False, System.Text.Encoding.ASCII)
FileOpen(1, yourfilename, OpenMode.Input)
FileClose(1)
Reset()
等数载,海棠开 2024-07-18 19:15:46

文件系统缓存中缓冲的文件数据将写入磁盘。 该数据通常是根据磁盘写入头的位置延迟写入的。 拥有千兆字节的缓存数据在技术上是可行的,因此可能需要相当长的时间。 如果这对您很重要,那么请考虑使用 FileOptions.WriteThrough 选项。

The file data that's buffered in the file system cache to be written to disk. That data is normally lazily written, based on the position of the disk write head. Having a gigabyte of cached data is technically possible so it can take quite a while. If this is important to you then consider the FileOptions.WriteThrough option instead.

九厘米的零° 2024-07-18 19:15:46

抽象级别太多,无法绝对确保数据写入光盘,一直到硬件级别。

性能不是很好,也不是万无一失,但是在单独的进程中写入文件后重新打开文件并检查大小或内容怎么样?

There's simply too many levels of abstraction to be absolutely sure that the data is written to the disc, right down to the hardware level.

Not brilliantly performant or foolproof, but how about re-opening the file once it is written in a seperate process and checking the size or contents?

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文