Can I close a file stream without calling Flush
(in C#)? I understood that Close
and Dispose
calls the Flush
method first.
Closes the current stream and releases any resources (such as sockets and file handles) associated with the current stream.
Clears all buffers for the current writer and causes any buffered data to be written to the underlying stream.
MSDN is not 100% clear, but Jon Skeet is saying "Flush", so do it before close/dispose. It won't hurt, right?
From FileStream.Close Method:
Any data previously written to the buffer is copied to the file before the file stream is closed, so it is not necessary to call Flush before invoking Close. Following a call to Close, any operations on the file stream might raise exceptions. After Close has been called once, it does nothing if called again.
Dispose is not as clear:
This method disposes the stream, by writing any changes to the backing store and closing the stream to release resources.
Remark: the commentators might be right, it's not 100% clear from the Flush:
Override Flush on streams that implement a buffer. Use this method to move any information from an underlying buffer to its destination, clear the buffer, or both. Depending upon the state of the object, you might have to modify the current position within the stream (for example, if the underlying stream supports seeking). For additional information see CanSeek.
When using the StreamWriter or BinaryWriter class, do not flush the base Stream object. Instead, use the class's Flush or Close method, which makes sure that the data is flushed to the underlying stream first and then written to the file.
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(); }
What can I say ... all files got the text - maybe this is just too little data?
var rnd = new Random(); var size = 1024*1024*10; var randomBytes = new byte[size]; rnd.NextBytes(randomBytes); using (var fileTest = System.IO.File.Open(@"c:\temp\fileNoCloseNoFlush.bin", FileMode.CreateNew)) { fileTest.Write(randomBytes, 0, randomBytes.Length); } using (var fileTest = System.IO.File.Open(@"c:\temp\fileCloseNoFlush.bin", FileMode.CreateNew)) { fileTest.Write(randomBytes, 0, randomBytes.Length); fileTest.Close(); } using (var fileTest = System.IO.File.Open(@"c:\temp\fileFlushNoClose.bin", FileMode.CreateNew)) { fileTest.Write(randomBytes, 0, randomBytes.Length); fileTest.Flush(); } using (var fileTest = System.IO.File.Open(@"c:\temp\fileCloseAndFlush.bin", FileMode.CreateNew)) { fileTest.Write(randomBytes, 0, randomBytes.Length); fileTest.Flush(); fileTest.Close(); }
And again - every file got its bytes ... to me it looks like it's doing what I read from MSDN: it doesn't matter if you call Flush or Close before dispose ... any thoughts on that?
You don't have to call Flush()
on Close()/Dispose()
, FileStream
will do it for you as you can see from its source code:
http://referencesource.microsoft.com/#mscorlib/system/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); } }
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With