关闭没有Flush()的文件流
本文关键字:文件 Flush | 更新日期: 2023-09-27 18:08:08
我可以关闭一个文件流而不调用Flush
(在c#中)吗?我理解Close
和Dispose
先调用Flush
方法
MSDN不是100%清楚,但Jon Skeet说"Flush",所以在close/dispose之前做。不会痛的,对吧?
文件流。关闭方法:
任何先前写入缓冲区的数据都被复制到之前的文件中文件流已关闭,因此没有必要在此之前调用Flush调用关闭。在调用Close之后,对文件的任何操作流可能引发异常。在Close被调用一次之后,它如果再次调用,不执行任何操作。
Dispose不清楚:
该方法通过将任何更改写入后台来处理流存储和关闭流以释放资源。
注释:评论员可能是对的,从Flush中并不是100%清楚:
<标题>测试:在实现缓冲区的流上重写Flush。使用这种方法将任何信息从底层缓冲区移动到其目的地,清除缓冲区,或者两者都清除。根据对象的状态,你可能需要修改流中的当前位置(for)例如,如果底层流支持查找)。额外的信息见CanSeek。
当使用StreamWriter或BinaryWriter类时,不要冲洗基流对象。相反,请使用类的Flush或Close方法,这确保了数据被刷新到底层流首先,然后写入文件。
var textBytes = Encoding.ASCII.GetBytes("Test123");
using (var fileTest = System.IO.File.Open(@"c:'temp'fileNoCloseNoFlush.txt", FileMode.CreateNew))
{
fileTest.Write(textBytes,0,textBytes.Length);
}
using (var fileTest = System.IO.File.Open(@"c:'temp'fileCloseNoFlush.txt", FileMode.CreateNew))
{
fileTest.Write(textBytes, 0, textBytes.Length);
fileTest.Close();
}
using (var fileTest = System.IO.File.Open(@"c:'temp'fileFlushNoClose.txt", FileMode.CreateNew))
{
fileTest.Write(textBytes, 0, textBytes.Length);
fileTest.Flush();
}
using (var fileTest = System.IO.File.Open(@"c:'temp'fileCloseAndFlush.txt", FileMode.CreateNew))
{
fileTest.Write(textBytes, 0, textBytes.Length);
fileTest.Flush();
fileTest.Close();
}
我能说什么……所有文件都有文本-也许这只是太少的数据?
<标题> Test2 h1> 一次-每个文件都有它的字节…对我来说,它看起来像是在做我从MSDN中读到的东西:在dispose之前调用Flush或Close并不重要……对此有什么想法吗? 标题>标题>您没有在Close()/Dispose()
上调用Flush()
, FileStream
将为您完成,您可以从其源代码:
http://referencesource.microsoft.com/mscorlib/系统/io/filestream.cs e23a38af5d11ddd3
[System.Security.SecuritySafeCritical] // auto-generated
protected override void Dispose(bool disposing)
{
// Nothing will be done differently based on whether we are
// disposing vs. finalizing. This is taking advantage of the
// weak ordering between normal finalizable objects & critical
// finalizable objects, which I included in the SafeHandle
// design for FileStream, which would often "just work" when
// finalized.
try {
if (_handle != null && !_handle.IsClosed) {
// Flush data to disk iff we were writing. After
// thinking about this, we also don't need to flush
// our read position, regardless of whether the handle
// was exposed to the user. They probably would NOT
// want us to do this.
if (_writePos > 0) {
FlushWrite(!disposing); // <- Note this
}
}
}
finally {
if (_handle != null && !_handle.IsClosed)
_handle.Dispose();
_canRead = false;
_canWrite = false;
_canSeek = false;
// Don't set the buffer to null, to avoid a NullReferenceException
// when users have a race condition in their code (ie, they call
// Close when calling another method on Stream like Read).
//_buffer = null;
base.Dispose(disposing);
}
}
我一直在跟踪一个新引入的错误,该错误似乎表明。net 4在处理流时不能可靠地将更改刷新到磁盘(与。net 2.0和3.5不同,它们总是可靠地这样做)。
. net 4的FileStream类在。net 4中已经进行了大量的修改,而Flush*()方法已经被重写,类似的注意似乎已经忘记了. dispose()。这会导致文件不完整。
既然你已经说过你理解close &dispose调用flush方法,如果它没有被用户代码显式调用,我相信(通过关闭不flush)您实际上希望有可能丢弃对FileStream
所做的更改,如果必要的话。
如果这是正确的,单独使用FileStream
是没有帮助的。您需要将此文件加载到MemoryStream
(或数组,取决于您如何修改其内容)中,然后决定是否要在完成后保存更改。
显然,这样做的一个问题是文件大小。FileStream
使用有限大小的写缓冲区来加快操作,但是一旦它们耗尽,就需要刷新更改。由于。net的内存限制,如果你需要完全保存它们,你只能期望在内存中加载更小的文件。
一个更简单的替代方法是使磁盘复制文件的,并使用普通的FileStream
处理它。完成后,如果需要放弃更改,只需删除临时文件,否则将原始文件替换为修改后的副本。
将FileStream
包裹在BufferedStream
中,并在缓冲流之前关闭文件流。
var fs = new FileStream(...);
var bs = new BufferedStream(fs, buffersize);
bs.Write(datatosend, 0, length);
fs.Close();
try {
bs.Close();
}
catch (IOException) {
}
在大循环中使用Flush()是值得的。当你必须在一个循环中读写一个大文件时。在其他情况下,缓冲区或计算机足够大,在关闭()之前不进行一次Flush()也没关系。
示例:你必须读取一个大文件(一种格式)并以。txt格式写入
StreamWriter sw = .... // using StreamWriter
// you read the File ...
// and now you want to write each line for this big File using WriteLine ();
for ( .....) // this is a big Loop because the File is big and has many Lines
{
sw.WriteLine ( *whatever i read* ); //we write here somrewhere ex. one .txt anywhere
sw.Flush(); // each time the sw.flush() is called, the sw.WriteLine is executed
}
sw.Close();
在这里使用Flush()是非常重要的;因为否则每个writeLine都被保存在缓冲区中,直到缓冲区满了或者直到程序到达sw.close();
我希望这对理解Flush
我认为使用简单的using语句是安全的,它在调用GetBytes();
之后关闭流public static byte[] GetBytes(string fileName)
{
byte[] buffer = new byte[4096];
using (FileStream fs = new FileStream(fileName))
using (MemoryStream ms = new MemoryStream())
{
fs.BlockCopy(ms, buffer, 4096); // extension method for the Stream class
fs.Close();
return ms.ToByteArray();
}
}