I have a StreamWriter which underlying stream is a FileStream. Will the following code guarantee that the FileStream also flushes its buffer into the actual file on the file system, or do I need to explicitly call Flush() on the FileStream?
using (var fs = new FileStream("blabla", FileMode.Append)) {
using (var sw = new StreamWriter(fs)) {
sw.WriteLine("Hello, I want to be flushed.");
sw.Flush(); //I need this to also flush onto the file, not just to the FileStream
}
}
As per MSDN, “Flushing the stream will not flush its underlying encoder unless you explicitly call Flush or Close“, but I do not know if a FileStream can be considered an “underlying encoder”.
Also, if I don’t specify FileOptions.WriteThrough, am I guaranteed that the OS will eventually write the flushed line onto the disk even if the program crashes before the two streams have been closed (assuming for example no using {} blocks, only a call to Flush())?
In my scenario I need to leave the stream open (for logging) so I cannot use using {} blocks, but I would like to make sure data will always be written to the disk even if the program crashes. I can afford to lose data if there is a power shutdown and the OS has not flushed onto the disk, but otherwise I need the OS to eventually flush even if I never properly call Close() on the stream.
Yes, calling
FlushonStreamWriterwill cause the underlying stream to beFlushed. The 4.5 version calls a privateFlush(bool,bool)function, which ends with:Where
flushStreamis the first parameter,this.streamis the stream that theStreamWriterwas constructed on, and the call inFlush()isFlush(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
StreamWriterusingfs, you shouldn’t perform any direct actions onfsyourself.The part you quoted from MSDN relates to the later sentences:
That is, you may have passed data to
Writesuch that you’ve given it some Unicode surrogates, but not a complete character.Flushwill not write those surrogates to the stream. So long as you’re always passing well formed (complete) strings toWrite, you do not need to concern yourself about this.