用户登录
用户注册

分享至

我应该为流对象调用 Close() 还是 Dispose()?

  • 作者: 看我名字干啥
  • 来源: 51数据库
  • 2022-12-15

问题描述

Stream、StreamReader、StreamWriter 等类实现了IDisposable 接口.这意味着,我们可以对这些类的对象调用 Dispose() 方法.他们还定义了一个名为 Close() 的 public 方法.现在这让我很困惑,一旦我完成了对象,我应该调用什么?如果我同时调用两者呢?

Classes such as Stream, StreamReader, StreamWriter etc implements IDisposable interface. That means, we can call Dispose() method on objects of these classes. They've also defined a public method called Close(). Now that confuses me, as to what should I call once I'm done with objects? What if I call both?

我当前的代码是这样的:

My current code is this:

using (Stream responseStream = response.GetResponseStream())
{
   using (StreamReader reader = new StreamReader(responseStream))
   {
      using (StreamWriter writer = new StreamWriter(filename))
      {
         int chunkSize = 1024;
         while (!reader.EndOfStream)
         {
            char[] buffer = new char[chunkSize];
            int count = reader.Read(buffer, 0, chunkSize);
            if (count != 0)
            {
               writer.Write(buffer, 0, count);
            }
         }
         writer.Close();
      }
      reader.Close();
   }
}

如您所见,我编写了 using() 构造,它会自动调用每个对象上的 Dispose() 方法.但我也调用了 Close() 方法.是吗?

As you see, I've written using() constructs, which automatically call Dispose() method on each object. But I also call Close() methods. Is it right?

请建议我使用流对象时的最佳实践.:-)

Please suggest me the best practices when using stream objects. :-)

MSDN 示例不使用 using() 构造,并调用 Close() 方法:

MSDN example doesn't use using() constructs, and call Close() method:

  • 如何:使用 FTP 下载文件

好用吗?

推荐答案

快速跳转到 Reflector.NET 可以看到 StreamWriter 上的 Close() 方法是:

A quick jump into Reflector.NET shows that the Close() method on StreamWriter is:

public override void Close()
{
    this.Dispose(true);
    GC.SuppressFinalize(this);
}

而 StreamReader 是:

public override void Close()
{
    this.Dispose(true);
}

StreamReader 中的 Dispose(bool disposing) 覆盖是:

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;
            /* deleted for brevity */
            base.Dispose(disposing);
        }
    }
}

StreamWriter 方法类似.

所以,阅读代码很明显你可以调用 Close() &Dispose() 在流上按您喜欢的频率和顺序.它不会以任何方式改变行为.

So, reading the code it is clear that that you can call Close() & Dispose() on streams as often as you like and in any order. It won't change the behaviour in any way.

所以这归结为使用 Dispose()、Close() 和/或 using ( ... ){ ... }.

So it comes down to whether or not it is more readable to use Dispose(), Close() and/or using ( ... ) { ... }.

我个人的偏好是 using ( ... ) { ... } 应该尽可能使用,因为它可以帮助你不用剪刀跑".

My personal preference is that using ( ... ) { ... } should always be used when possible as it helps you to "not run with scissors".

但是,虽然这有助于正确性,但它确实降低了可读性.在 C# 中,我们已经有过多的关闭花括号,那么我们如何知道哪个真正在流上执行了关闭?

But, while this helps correctness, it does reduce readability. In C# we already have plethora of closing curly braces so how do we know which one actually performs the close on the stream?

所以我认为最好这样做:

So I think it is best to do this:

using (var stream = ...)
{
    /* code */

    stream.Close();
}

它不会影响代码的行为,但确实有助于提高可读性.

It doesn't affect the behaviour of the code, but it does aid readability.

软件
前端设计
程序设计
Java相关