处置流式阅读器是否关闭流?

我正在发送一个流到方法上写,在这些方法中,我使用了一个二进制阅读器/书写器。当读写器/写入器被 using释放或者没有被引用时,流是否也被关闭? ? ?

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

79134 次浏览

通过“使用”关键字或显式调用释放来释放的流

是的。您可以通过使用反射器查看实现来验证这一点。

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

是的。调用 Dispose () on 和 IDisposable (“ using”会这样做)应该会让一个对象清理它的所有资源。这包括流刷新和关闭它们的文件描述符。

在您的情况下,如果您想将它传递给其他方法,那么您需要确保这些方法不会在 using 块中执行读/写操作。

是的,当您调用 Dispose时,StreamReaderStreamWriterBinaryReaderBinaryWriter都关闭/释放它们的底层流。如果读取器/写入器只是被垃圾收集,那么它们 不要将处理流-您应该始终处理读取器/写入器,最好使用 using语句。(事实上,这些类都没有终结器,也不应该有终结器。)

就个人而言,我更喜欢有一个用于流的语句。您可以相当整齐地嵌套没有大括号的 using语句:

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

尽管流的 using语句有些多余(除非 StreamReader构造函数抛出一个异常) ,但我认为这是最佳实践,因为如果您去掉了 StreamReader,只是在以后直接使用流,那么您就已经拥有了正确的处置语义。

如果需要,修复这个问题的一个简单方法是重写 StreamWriter 类 Dispose 方法。点击这里查看我的文章,了解如何做到这一点的代码:

是否关闭基础流?

这是一个旧的,但我今天想做类似的事情,发现事情已经改变了。自从。净值为4.5,有一个 leaveOpen的论点:

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

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

来自 Msdn 页面 的流读取器构造函数(流) :

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

那就剩下 detectEncodingFromByteOrderMarks了,从 译自: http://www.dotnetframework.org/default.aspx/DotNET/DotNET/8@0/untmp/whidbey/REDBITS/ndp/clr/src/BCL/System/IO/StreamReader@cs/1/StreamReader@cs判断是 true

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


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

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

虽然晚了六年,但也许这能帮到别人。

当连接被释放时,StreamReader 会关闭连接。然而,“ using (Stream Stream = ...){ ... }”和 StreamReader/StreamWriter 可能导致 Stream 被释放两次: (1)当 StreamReader 对象被释放时(2)和 Stream using 块关闭时。这导致在运行 VS 的代码分析时出现 CA2202警告。

另一个解决方案直接取自 CA2202页面,即使用 try/finally 块。如果安装正确,这将只关闭连接一次。

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

Stream stream = null;
try
{
stream = new FileStream("file.txt", FileMode.OpenOrCreate);
using (StreamWriter writer = new StreamWriter(stream))
{
stream = null;
// Use the writer object...
}
}
finally
{
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...
}