处理streamreader会关闭流吗?

时间:2009-06-30 18:17:55

标签: c# stream streamreader

我正在向要写入的方法发送一个流,在这些方法中我使用的是二进制阅读器/ wrtier。当读者/作者被释放时,无论是using还是仅当它被引用时,流也被关闭了?

我会发送一个BinaryReader / Writer,但我也在使用StreamReader(也许我应该绕过它。我只是将它用于GetLine和ReadLine)。如果每次作家/读者关闭时关闭流都会非常麻烦。

7 个答案:

答案 0 :(得分:189)

是的,StreamReaderStreamWriterBinaryReaderBinaryWriter在您呼叫Dispose时关闭/处置其基础流。如果读者/作者只是垃圾收集,他们处理流 - 你应该总是处理读者/作者,最好用using语句。 (事实上​​,这些类都没有终结器,也不应该有终结器。)

我个人更喜欢为流提供一个using语句。您可以非常巧妙地嵌套using语句而不是括号:

using (Stream stream = ...)
using (StreamReader reader = new StreamReader(stream, Encoding.Whatever))
{
}

即使流的using语句有点多余(除非StreamReader构造函数抛出异常),我认为如果你摆脱StreamReader和只需在以后直接使用流,您就已经拥有了正确的处理语义。

答案 1 :(得分:38)

这是一个旧的,但我想今天做类似的事情,发现事情已经发生了变化。从.net 4.5开始,有一个leaveOpen参数:

public StreamReader( Stream stream, Encoding encoding, bool detectEncodingFromByteOrderMarks, int bufferSize, bool leaveOpen )

唯一的问题是,为其他参数设置的内容并不完全明显。这是一些帮助:

来自 the msdn page 的StreamReader构造函数(流):

  

此构造函数将编码初始化为UTF8Encoding,即   BaseStream属性使用stream参数和内部   缓冲区大小为1024字节。

刚刚离开detectEncodingFromByteOrderMarks the source code 判断true

public StreamReader(Stream stream)
        : this(stream, true) {
}

public StreamReader(Stream stream, bool detectEncodingFromByteOrderMarks)
        : this(stream, Encoding.UTF8, detectEncodingFromByteOrderMarks, DefaultBufferSize) {
}

如果暴露了其中一些默认值或者参数是可选的,那么我们可以只指定我们想要的那些默认值。

答案 2 :(得分:27)

是的,确实如此。您可以通过使用Reflector查看实现来验证这一点。

protected override void Dispose(bool disposing)
{
    try
    {
        if ((this.Closable && disposing) && (this.stream != null))
        {
            this.stream.Close();
        }
    }
    finally
    {
        if (this.Closable && (this.stream != null))
        {    
            this.stream = null;    
            this.encoding = null;
            this.decoder = null;
            this.byteBuffer = null;
            this.charBuffer = null;
            this.charPos = 0;
            this.charLen = 0;
            base.Dispose(disposing);
        }
    }
}

答案 3 :(得分:10)

迟到六年但也许这可能对某人有所帮助。

StreamReader在处理时会关闭连接。但是,"使用(Stream stream = ...){...}"使用StreamReader / StreamWriter可以导致Stream被处理两次:(1)当StreamReader对象被释放时(2)以及Stream using block关闭时。运行VS的代码分析时会出现CA2202警告。

直接从CA2202页面获取的另一个解决方案是使用try / finally块。正确设置,这只会关闭一次连接。

CA2202的底部附近,Microsoft建议使用以下内容:

Stream stream = null;
try
{
    stream = new FileStream("file.txt", FileMode.OpenOrCreate);
    using (StreamWriter writer = new StreamWriter(stream))
    {
        stream = null;
        // Use the writer object...
    }
}
finally
{
    if(stream != null)
        stream.Dispose();
}

而不是......

// Generates a CA2202 warning
using (Stream stream = new FileStream("file.txt", FileMode.Open))
using (XmlReader reader = new XmlReader (stream))
{
    // Use the reader object...
}

答案 4 :(得分:2)

是。调用Dispose()和IDisposable(“使用”)应该使对象清理其所有资源。这包括刷新和关闭文件描述符的流。

如果您希望将其传递给其他方法,那么您需要确保这些方法不会在使用块中进行读/写。

答案 5 :(得分:1)

如果需要,一种简单的方法是重写StreamWriter类Dispose方法。请参阅我的帖子,了解有关如何操作的代码:

Does .Disposing a StreamWriter close the underlying stream?

答案 6 :(得分:-3)

通过“使用”关键字或明确调用dispose来处理流