C# 处理 streamreader 会关闭流吗?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/1065168/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-06 07:22:33  来源:igfitidea点击:

Does disposing streamreader close the stream?

c#streamstreamreader

提问by Nefzen

I am sending a stream to methods to write on, and in those methods I am using a binary reader/wrtier. When the reader/writer gets disposed, either by usingor just when it is not referenced, is the stream closed as well??

我正在向要写入的方法发送流,并且在这些方法中我使用的是二进制读取器/写入器。当读取器/写入器被释放时,无论using是被引用还是没有被引用时,流是否也关闭了??

I would send a BinaryReader/Writer, but I am using a StreamReader too (maybe I should go around that. I am only using that for GetLine and ReadLine). This is quite troublesome if it closes the stream each time a writer/reader gets closed.

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

采纳答案by Jon Skeet

Yes, StreamReader, StreamWriter, BinaryReaderand BinaryWriterall close/dispose their underlying streams when you call Disposeon them. They don'tdispose of the stream if the reader/writer is just garbage collected though - you should always dispose of the reader/writer, preferrably with a usingstatement. (In fact, none of these classes have finalizers, nor should they have.)

是的,StreamReaderStreamWriterBinaryReaderBinaryWriter所有关闭/处置其底层流时,你叫Dispose他们。如果读取器/写入器只是垃圾收集,它们不会处理流 - 您应该始终处理读取器/写入器,最好使用using语句。(事实上​​,这些类都没有终结器,也不应该有。)

Personally I prefer to have a using statement for the stream as well. You can nest usingstatements without braces quite neatly:

就我个人而言,我更喜欢为流使用 using 语句。您可以using非常整齐地嵌套没有大括号的语句:

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

Even though the usingstatement for the stream is somewhat redundant (unless the StreamReaderconstructor throws an exception) I consider it best practice as then if you get rid of the StreamReaderand just use the stream directly at a later date, you'll already have the right disposal semantics.

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

回答by Ahmed Said

the stream disposed either by "using" keyword or calling dispose explicitly

通过“使用”关键字或显式调用 dispose 处理的流

回答by Brian Rasmussen

Yes, it does. You can verify this by looking at the implementation with Reflector.

是的,它确实。您可以通过查看 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);
        }
    }
}

回答by Joe M

Yes. Calling Dispose() on and IDisposable (which "using" does) should make an object clean up all of its resources. This includes streams flushing and closing their file descriptors.

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

If, in your case, you want to pass it in to other methods, then you need to make sure that those methods do not do their reading/writing in a using block.

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

回答by Aaron Murgatroyd

An easy way to fix this if you need to is to override the StreamWriter classes Dispose method. See my post here for the code on how to do it:

如果需要,解决此问题的一种简单方法是覆盖 StreamWriter 类的 Dispose 方法。有关如何执行此操作的代码,请参阅我的帖子:

Does .Disposing a StreamWriter close the underlying stream?

.Disposing a StreamWriter 会关闭底层流吗?

回答by acarlon

This is an old one, but I wanted to do something similar today and found that things have changed. Since .net 4.5, there is a leaveOpenargument:

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

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

The only problem is that it is not entirely obvious what to set for the other parameters. Here is some help:

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

From the msdn pagefor StreamReader Constructor (Stream):

从StreamReader Constructor (Stream)的 msdn 页面

This constructor initializes the encoding to UTF8Encoding, the BaseStream property using the stream parameter, and the internal buffer size to 1024 bytes.

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

That just leaves detectEncodingFromByteOrderMarkswhich judging by the source codeis true

那只剩下从源代码detectEncodingFromByteOrderMarks来看是true

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

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

It would be nice if some of those defaults were exposed or if the arguments were optional so that we could just specify the ones that we want.

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

回答by Sunsetquest

Six years late but maybe this might help someone.

晚了六年,但也许这可能对某人有所帮助。

StreamReader does close the connection when it is disposed. However, "using (Stream stream = ...){...}" with StreamReader/StreamWriter can result in the Stream being disposed of twice: (1) when the StreamReader object is disposed (2) and when the Stream using block closes. This results in a CA2202 warning when running VS's code analysis.

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

Another solution, taken directly from the CA2202page, is to use a try/finally block. Setup correctly, this will only close the connection once.

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

Near the bottom of CA2202, Microsoft recommends to use the following:

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

instead of...

代替...

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