What is the difference between StreamWriter.Flush() and StreamWriter.Close()?
StreamWriter.Flush()
can be called any time you need to clear the buffer, and the stream will remain open.
StreamWriter.Close()
is for closing the stream, at which point the buffer is also flushed.
But you shouldn't really need to call either of these. Any time I see a .Close()
in code I take that as a code smell, because it usually means an unexpected exception could cause the resource to be left open. What you should do, is create your StreamWriter
variable in a using block, like this:
using (var writer = new StreamWriter("somefilepath.txt"))
{
// write a bunch of stuff here
} // the streamwriter WILL be closed and flushed here, even if an exception is thrown.
Do I need to do StreamWriter.flush()?
Scratch the previous answer - I hadn't noticed that you were using two wrappers around the same stream. That feels somewhat risky to me.
Either way, I'd put the StreamWriter
and BinaryWriter
in their own using
blocks.
Oh, and yes, it's legal to call ToArray()
on the MemoryStream
- the data is retained even after it's disposed.
If you really want to use the two wrappers, I'd do it like this:
using (MemoryStream stream = new MemoryStream())
{
using (StreamWriter normalWriter = new StreamWriter(stream))
using (BinaryWriter binaryWriter = new BinaryWriter(stream))
{
foreach(...)
{
binaryWriter.Write(number);
binaryWriter.Flush();
normalWriter.WriteLine(name); //<~~ easier to read afterward.
normalWriter.Flush();
}
}
return MemoryStream.ToArray();
}
I have to say, I'm somewhat wary of using two wrappers around the same stream though. You'll have to keep flushing each of them after each operation to make sure you don't end up with odd data. You could set the StreamWriter
's AutoFlush
property to true to mitigate the situation, and I believe that BinaryWriter
currently doesn't actually require flushing (i.e. it doesn't buffer any data) but relying on that feels risky.
If you have to mix binary and text data, I'd use a BinaryWriter
and explicitly write the bytes for the string, fetching it with Encoding.GetBytes(string)
.
difference between flush and close function in case of filewriter in java
flush() writes the content of the buffer to the destination and makes the buffer empty for further data to store but it does not closes the stream permanently. That means you can still write some more data to the stream.
But close() closes the stream permanently. If you want to write some data further, then you have to reopen the stream again and append the data with the existing ones.
Will StreamWriter.Flush() also call FileStream.Flush()?
Yes, calling Flush
on StreamWriter
will cause the underlying stream to be Flush
ed. The 4.5 version calls a private Flush(bool,bool)
function, which ends with:
if (flushStream)
{
this.stream.Flush();
}
Where flushStream
is the first parameter, this.stream
is the stream that the StreamWriter
was constructed on, and the call in Flush()
is Flush(true,true)
.
(Older parts of answer - I was being very roundabout in answering. Moved most relevant part of answer to top)
It's not explicitly spelled out in the documentation anywhere I can find it, but any stream class that is constructed by passing it another stream should be assumed to "take ownership" of that stream (unless it's specifically called out otherwise).
That is, once you've constructed the StreamWriter
using fs
, you shouldn't perform any direct actions on fs
yourself.
The part you quoted from MSDN relates to the later sentences:
This allows the encoder to keep its state (partial characters) so that it can encode the next block of characters correctly. This scenario affects UTF8 and UTF7 where certain characters can only be encoded after the encoder receives the adjacent character or characters.
That is, you may have passed data to Write
such that you've given it some Unicode surrogates, but not a complete character. Flush
will not write those surrogates to the stream. So long as you're always passing well formed (complete) strings to Write
, you do not need to concern yourself about this.
Is there a benefit in closing StreamReader (or StreamWriter) when I close Stream explicitly?
You do need to close a StreamWriter
(generally via the using
block), or else data in its buffer could be lost.
Because both StreamReader
and StreamWriter
default to closing the stream automatically, if you want to eliminate one using
block from your code, it should be the Stream
that you remove from using
.
If you can't do that, for example you've borrowed the Stream
from elsewhere that doesn't want you to close it, then you must use the leaveOpen
parameter you're already aware of. The reason that you can't just omit the using
statement for a StreamReader
/StreamWriter
in order to leave it open, is that the garbage collector will still trigger some cleanup (although not as much) since the object is unreachable... only this will now occur at an unrelated time, creating an unpredictable bug that's very hard to find.
It is indeed ugly that you can't specify leaveOpen
without explicitly controlling the buffer size, etc. May I suggest a helper method along the lines of StreamReader CreateStreamReaderLeaveOpen(Stream)
?
Flush StreamWriter at the end of its lifetime
First of all, using a singleton creates problems in its own right, and this did not need another proof. Here, it's cleanup for a disguised global. The StreamWriter
does not auto-flush on program end and according to the documentation,
You must call Close to ensure that all data is correctly written out to the underlying stream.
Thanks to an answer to "Self-closing StreamWriter singleton" from @PeterDuniho a possible solution could be changing the constructor to
private Foo()
{
this.os = System.IO.File.CreateText( "D:/tmp/test" );
System.AppDomain.CurrentDomain.ProcessExit +=
(sender, eventArgs) => this.os.Close();
}
Considering the problem of calling Close()
in the destructor, I should not have ignored the "finalizers are not of much use anyway" written all over the place. In this case, as garbage collection does not use a specific order, the StreamWriter
object has already been collected and cannot be closed in its resurrected zombie state.
Does .Disposing a StreamWriter close the underlying stream?
StreamWriter.Close()
just calls StreamWriter.Dispose()
under the bonnet, so they do exactly the same thing.StreamWriter.Dispose()
does close the underlying stream.
Reflector is your friend for questions like this :)
Related Topics
How to Make a Combobox Non-Editable in .Net
How to Fix Wpf Error: "Program Does Not Contain a Static 'Main' Method Suitable for an Entry Point"
How to Tryparse for Enum Value
Html.Enumdropdownlistfor: Showing a Default Text
Is There a Serializable Generic Key/Value Pair Class in .Net
Connect to Active Directory via Ldap
How to Get a List<String> Collection of Values from App.Config in Wpf
How to Get Byte Array Properly from an Web API Method in C#
Get Substring - Everything Before Certain Char
Multi Processes Read&Write One File
How to Modify Existing Xml File with Xmldocument and Xmlnode in C#
How to Extend C# Built-In Types, Like String