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 } }
根据MSDN,“刷新流不会刷新其底层编码器,除非您明确调用Flush或Close”,但我不知道FileStream是否可以被视为“底层编码器”.
另外,如果我没有指定FileOptions.WriteThrough,我保证操作系统最终会将刷新的行写入磁盘,即使程序在两个流关闭之前崩溃(假设例如没有使用{}块,打电话给Flush())?
在我的场景中,我需要保持流打开(用于记录),所以我不能使用{}块,但我想确保即使程序崩溃,数据也将始终写入磁盘.如果电源关闭并且操作系统没有刷新到磁盘上,我可以负担得起丢失数据,但是否则我需要操作系统最终刷新,即使我从未正确调用流上的Close().
解决方法
if (flushStream) { this.stream.Flush(); }
其中flushStream是第一个参数,this.stream是构造StreamWriter的流,而Flush()中的调用是Flush(true,true).
(答案的旧部分 – 我在回答时非常迂回.将答案的最相关部分移到顶部)
它没有在我可以找到的任何地方的文档中明确说明,但是通过传递另一个流构造的任何流类应该被假定为“取得该流的所有权”(除非另有特别调用).
也就是说,一旦使用fs构造了StreamWriter,就不应该自己对fs执行任何直接操作.
您从MSDN引用的部分与后面的句子有关:
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.
也就是说,您可能已经将数据传递给Write,这样您就可以给它一些Unicode代理,但不是完整的字符. Flush不会将这些代理写入流中.只要你总是将格式良好的(完整的)字符串传递给Write,你就不需要关心这一点了.