【问题标题】:Is there a benefit in closing StreamReader (or StreamWriter) when I close Stream explicitly?当我明确关闭 Stream 时,关闭 StreamReader(或 StreamWriter)有什么好处吗?
【发布时间】:2017-10-06 13:46:07
【问题描述】:

我有以下代码。在这里,我将StreamReader 构造函数与leaveOpen: true 一起使用,为此我需要提供I manage to get their default values 的先前参数。这很麻烦。由于我将streamusing 一起使用,我对使用StreamReaderusing 有什么好处吗?如果是StreamWriter,答案会改变吗?

using (Strem stream = ...)
{
    ...
    using (StreamReader sr = new StreamReader(stream, Encoding.UTF8, true, 1024, true))
    {
        ...
    }
    ...
}

如果改用以下代码,我会丢失什么?

using (Strem stream = ...)
{
    ...
    StreamReader sr = new StreamReader(stream);

    ...

    ...
}

【问题讨论】:

  • 在 using 语句完成后关闭。无需显式关闭。一个 try/finally 被遵守,它的调用接近两者。
  • @Botonomous 我想问的是如果我不使用内部使用会发生什么
  • 试试看吧。我想 GC 会在流超出范围后捡起它。为了获得最佳实践,您应该保留它。
  • @Botonomous 我不喜欢对其他参数使用默认值的必要性。

标签: c# stream streamreader idisposable


【解决方案1】:

您确实需要关闭StreamWriter(通常通过using 块),否则其缓冲区中的数据可能会丢失。

因为StreamReaderStreamWriter都默认自动关闭流,如果你想从你的代码中删除一个using块,它应该是你从using中删除的Stream

如果你不能这样做,例如你从别处借了Stream不想让你关闭它,那么你必须使用你已经知道的leaveOpen参数。您不能仅仅省略 using 语句的 StreamReader/StreamWriter 以使其保持打开状态的原因是垃圾收集器仍会触发一些清理(尽管不是那么多),因为对象是无法访问...现在只会在不相关的时间发生这种情况,从而产生难以发现的不可预测的错误。

如果不明确控制缓冲区大小等,您不能指定leaveOpen 确实很难看。我可以建议一个类似于StreamReader CreateStreamReaderLeaveOpen(Stream) 的辅助方法吗?

【讨论】:

    【解决方案2】:

    因为您在处理StreamReader does nothing execpt call the the Dispose method of the TextReader class 的构造函数中将leaveOpen 设置为true,而它本身什么都不做。

    protected override void Dispose(bool disposing)
    {
        // Dispose of our resources if this StreamReader is closable.
        // Note that Console.In should be left open.
        try {
            // Note that Stream.Close() can potentially throw here. So we need to 
            // ensure cleaning up internal resources, inside the finally block.  
            if (!LeaveOpen && disposing && (stream != null))
                stream.Close();
        }
        finally {
            if (!LeaveOpen && (stream != null)) {
                stream = null;
                encoding = null;
                decoder = null;
                byteBuffer = null;
                charBuffer = null;
                charPos = 0;
                charLen = 0;
                base.Dispose(disposing);
            }
        }
    }
    

    使用StreamWriter 确实会发生一些变化,因为it will not flush it's internal buffers to the underlying stream unless you dispose of the writer

    【讨论】:

    • 该问题还询问了StreamWriter,它在Dispose() 时执行操作(包括流上刷新)的条件要复杂得多。
    猜你喜欢
    • 2012-09-28
    • 1970-01-01
    • 2010-12-20
    • 2014-02-24
    • 1970-01-01
    • 1970-01-01
    • 2018-07-11
    • 2014-03-03
    相关资源
    最近更新 更多