Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/313.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# StreamWriter.Flush()还会调用FileStream.Flush()吗?_C#_.net_Stream_Filestream_Flush - Fatal编程技术网

C# StreamWriter.Flush()还会调用FileStream.Flush()吗?

C# StreamWriter.Flush()还会调用FileStream.Flush()吗?,c#,.net,stream,filestream,flush,C#,.net,Stream,Filestream,Flush,我有一个StreamWriter,它的底层流是FileStream。以下代码是否保证FileStream也会将其缓冲区刷新到文件系统上的实际文件中,或者我是否需要在FileStream上显式调用Flush() using (var fs = new FileStream("blabla", FileMode.Append)) { using (var sw = new StreamWriter(fs)) { sw.WriteLine("Hello, I want to b

我有一个StreamWriter,它的底层流是
FileStream
。以下代码是否保证
FileStream
也会将其缓冲区刷新到文件系统上的实际文件中,或者我是否需要在
FileStream
上显式调用
Flush()

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
    }
}
正如“除非显式调用flush或Close,否则刷新流不会刷新其底层编码器”,但我不知道文件流是否可以被视为“底层编码器”

另外,如果我没有指定FileOptions.WriteThrough,我是否可以保证即使程序在两个流关闭之前崩溃,操作系统最终也会将刷新的行写入磁盘(例如,假设没有
使用{}
块,只调用
Flush()


在我的场景中,我需要让流保持打开状态(用于日志记录),这样我就不能使用
使用{}
块,但我想确保即使程序崩溃,数据也会一直写入磁盘。如果断电并且操作系统没有刷新到磁盘上,我可以承受数据丢失的损失,但是如果没有,我需要操作系统最终刷新,即使我从未正确调用流上的
Close()

如果与使用块一起使用,则保证流处理

对于流链,关闭最外层的流(在链的顶端)

Flush方法强制立即写入内部缓冲区。当流
关闭时,将自动调用Flush,因此您无需执行以下操作

s.Flush();s、 Close()

因此,当最顶层的流关闭时,它会刷新,然后关闭底层流,底层流也会刷新其中的内容

<强>例如< /强>考虑此链

FileStream->GZipStream->StreamWriter
所以,当你关闭StreamWriter的时候

StreamWriter
刷新并关闭。它也会关闭不存在的
GZipStream

GzipStream
刷新并关闭。它还关闭底层的
FileStream


FileStream
刷新
关闭
是,在
StreamWriter
上调用
Flush
将导致底层流被
Flush
加密。4.5版本调用私有
刷新(bool,bool)
函数,该函数以:

if (flushStream)
{
    this.stream.Flush();
}
其中
flushStream
是第一个参数,
this.stream
是构建
StreamWriter
的流,
Flush()
中的调用是
Flush(true,true)


(答案的老部分-我在回答时非常迂回。将答案中最相关的部分移到顶部)

在我能找到它的任何地方,文档中都没有明确说明它,但是通过将另一个流传递给它而构造的任何流类都应该被假定为“拥有”该流(除非另有特别说明)

也就是说,一旦使用
fs
构建了
StreamWriter
,就不应该对自己执行任何直接操作


您从MSDN中引用的部分与后面的句子有关:

这允许编码器保持其状态(部分字符),以便正确编码下一个字符块。此场景影响UTF8和UTF7,其中某些字符只能在编码器接收到相邻字符后进行编码

也就是说,您可能已经将数据传递给了
Write
,这样您就给了它一些Unicode代理,但不是一个完整的字符
Flush
不会将这些代理写入流。只要您总是将格式良好(完整)的字符串传递给
Write
,您就不必担心这一点



您为什么不亲自尝试?我想知道这种行为是否有保证,我们是否可以依赖它,而不是它是否在大多数时间都有效。是的,它将刷新底层流。清除当前写入程序的所有缓冲区,并将所有缓冲数据写入基础流。谢谢,我知道关闭StreamWriter会关闭文件流,但问题的第一部分涉及Flush()是否也在级联。问题的第二部分涉及到,如果文件流在崩溃之前没有被处理(例如,没有使用块),但是调用了Flush(),操作系统是否最终会将其内部缓冲区写入物理磁盘(当然前提是没有操作系统崩溃或断电)。@ErwinMayer如我所说,
flush
在流关闭或缓冲区被填充时自动调用。当最顶端的流关闭时,它会刷新,然后关闭底层流,底层流也会刷新这些流。@erwinmair tht将是一个不同的场景。因为你可以通过使用
using
来避免它。你添加了很多信息关于流处于
Close
d时会发生什么,但是OP询问调用
Flush
时会发生什么。他们不想(此时)关闭流。顺便说一句@Fake.It.Til.U.Make.It并不总是可以使用“using”,在我的例子中,数百个StreamWriter需要在一个循环中同时打开,因此不能用括号表示。谢谢,这非常有帮助。问题的第二部分呢?关于保证操作系统将在某个时间点实际写入刷新,即使流从未正确关闭,并且FileOptions.WriteThrough未在FileStream构造函数中指定?@ErwinMayer-我不确定我是否理解这个问题。如果您绝对地、肯定地必须确保这些数据到达磁盘,那么您几乎肯定会需要指定
WriteThrough
——但您还需要一台具有