我将一个流发送到要写入的方法,并且在这些方法中我使用二进制读取器/wrtier。当读取器/写入器被处置时,可以通过 using 或者只是当它没有被引用时,流也关闭吗?

我会发送一个 BinaryReader/Writer,但我也在使用 StreamReader(也许我应该绕过它。我只将其用于 GetLine 和 ReadLine)。如果每次写入器/读取器关闭时它都会关闭流,那么这是非常麻烦的。

有帮助吗?

解决方案

是的, StreamReader, StreamWriter, BinaryReaderBinaryWriter 当您调用时,所有都关闭/处置其底层流 Dispose 在他们。他们 如果读取器/写入器只是垃圾收集,则处置流 - 您应该始终处置读取器/写入器,最好使用 using 陈述。(事实上​​,这些类都没有,也不应该有。)

就我个人而言,我更喜欢为流提供一个 using 语句。你可以筑巢 using 不带大括号的语句非常整齐:

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

尽管 using 流的语句有些多余(除非 StreamReader 构造函数抛出异常)我认为这是最佳实践,因为如果你摆脱了 StreamReader 并且稍后直接使用该流,您就已经拥有了正确的处理语义。

其他提示

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

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

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

MSDN 页面 对于 StreamReader 构造函数(流):

该构造函数初始化了对UTF8Encoding的编码,使用流参数的底流属性以及内部缓冲区大小为1024字节。

那只剩下 detectEncodingFromByteOrderMarks 由此判断 源代码true

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

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

如果公开其中一些默认值或者参数是可选的,这样我们就可以指定我们想要的参数,那就太好了。

是,它的作用。您可以通过查看与反射器实施验证这一点。

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);
        }
    }
}

六晚年但也许这会帮助别人。

的StreamReader做它被设置时关闭连接。然而,“使用(流流= ...){...}”与的StreamReader / StreamWriter的可以导致流被布置两次:(1)当StreamReader对象被设置(2),并且当流使用块关闭。运行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...
}

是。呼吁和IDisposable接口的Dispose()(其中“使用”一样)应该作出对象清理其所有资源。这包括冲洗和关闭它们的文件描述符流。

如果,你的情况,你想把它传递给其他的方法,那么你需要确保这些方法没有做好自己的读/在使用块的写入。

如果您需要是重写的StreamWriter类处置方法的一个简单方法解决此问题。请参见我的文章在这里就如何做到这一点的代码:

是否.Disposing一个StreamWriter关闭基础流?

流设置或者通过“使用”关键字或调用dispose明确地

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top