我知道.NET FileStream的Flush方法只将当前缓冲区写入磁盘,但根据Windows的磁盘驱动程序和硬盘固件,这不能保证数据实际上物理写入磁盘。是否有.NET或Win32方法可以给予我这样的保证?这样,如果在调用此方法返回后一纳秒断电,我仍然可以确定一切正常?
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缓冲区是空的,刷新(真)什么也没做?
umuewwlo2#
在Windows下,查看FlushFileBuffers(Win32 API)。
goqiplq23#
好吧,你可以关闭文件.... a.这很可能就可以了。实际上,随着HAL抽象化、虚拟化和磁盘硬件现在比几年前的 * 计算机 * 拥有更强的处理能力和缓存内存,你将不得不希望磁盘完成它的工作。事务性文件系统从未真正实现;-p当然,您也许可以考虑使用数据库作为后端,并使用它的事务系统。旁白:注意,并不是所有的流都能保证Flush()--例如,GZipStream等即使在刷新之后也会保留一个未提交数据的工作缓冲区--让它刷新 * 所有内容 * 的唯一方法是Close()它。
Flush()
GZipStream
Close()
gdrx4gfi4#
我注意到.NET 4 #Flush(true)实际上并不写入磁盘。我们遇到了数据损坏的奇怪问题,我在MS网站上找到了这个bug报告:错误报告的详细信息选项卡有一个测试程序,您可以运行它来显示问题;1.将一堆数据写入磁盘
fs.Flush(true)
FlushFileBuffers
yr9zkbsy5#
将缓冲区的内容刷新到磁盘有一个简单的答案。在WriteAllText函数之后,打开文件,关闭它,然后重置它下面是一个示例
My.Computer.FileSystem.WriteAllText(yourfilename, "hello", False, System.Text.Encoding.ASCII) FileOpen(1, yourfilename, OpenMode.Input) FileClose(1) Reset()
zbq4xfa06#
缓存在文件系统缓存中并要写入磁盘的文件数据。根据磁盘写入磁头的位置,这些数据通常是延迟写入的。缓存1 GB的数据在技术上是可行的,因此可能需要相当长的时间。如果这对您很重要,则考虑FileOptions.WriteThrough选项。
FileOptions.WriteThrough
8cdiaqws7#
有太多的抽象层次,以至于无法绝对确定数据是否被写入磁盘,一直到硬件层次。性能不是很好,也不是很简单,但是如果文件是在一个单独的进程中编写的,那么重新打开它并检查大小或内容怎么样?
7条答案
按热度按时间vjhs03f71#
斯特凡·S说:
我知道.NET FileStream的Flush方法只将当前缓冲区写入磁盘
不,.NET FileStream的Flush只将.NET缓冲区写入操作系统缓存,它不会将操作系统缓存刷新到磁盘。遗憾的是,关于此类的MSDN文档没有这样说。对于.NET〈4.0,您必须调用Flush + Win32的FlushFilebuffers:
对于.NET 4.0,您可以改用新的flush(true)方法。11/09/2012更新:微软的错误报告说它坏了,然后修复了,但没有说它是在什么版本或服务包中修复的!听起来像是错误,如果内部.NET FileStream缓冲区是空的,刷新(真)什么也没做?
umuewwlo2#
在Windows下,查看FlushFileBuffers(Win32 API)。
goqiplq23#
好吧,你可以关闭文件.... a.这很可能就可以了。实际上,随着HAL抽象化、虚拟化和磁盘硬件现在比几年前的 * 计算机 * 拥有更强的处理能力和缓存内存,你将不得不希望磁盘完成它的工作。
事务性文件系统从未真正实现;-p当然,您也许可以考虑使用数据库作为后端,并使用它的事务系统。
旁白:注意,并不是所有的流都能保证
Flush()
--例如,GZipStream
等即使在刷新之后也会保留一个未提交数据的工作缓冲区--让它刷新 * 所有内容 * 的唯一方法是Close()
它。gdrx4gfi4#
我注意到.NET 4 #Flush(true)实际上并不写入磁盘。我们遇到了数据损坏的奇怪问题,我在MS网站上找到了这个bug报告:
错误报告的详细信息选项卡有一个测试程序,您可以运行它来显示问题;
1.将一堆数据写入磁盘
fs.Flush(true)
。这不需要时间(比可能写入磁盘的速度快得多)。1.使用win32 API
FlushFileBuffers
。这需要很长时间。我正在切换到win32 FlushFileBuffers调用...
yr9zkbsy5#
将缓冲区的内容刷新到磁盘有一个简单的答案。在WriteAllText函数之后,打开文件,关闭它,然后重置它
下面是一个示例
zbq4xfa06#
缓存在文件系统缓存中并要写入磁盘的文件数据。根据磁盘写入磁头的位置,这些数据通常是延迟写入的。缓存1 GB的数据在技术上是可行的,因此可能需要相当长的时间。如果这对您很重要,则考虑
FileOptions.WriteThrough
选项。8cdiaqws7#
有太多的抽象层次,以至于无法绝对确定数据是否被写入磁盘,一直到硬件层次。
性能不是很好,也不是很简单,但是如果文件是在一个单独的进程中编写的,那么重新打开它并检查大小或内容怎么样?