LoginSignup
3
2

More than 5 years have passed since last update.

[C#] Stream と Reader/Writer の Dispose

Last updated at Posted at 2017-09-08

要約

  • Reader/Writer にも Dispose がある
  • 基本的に Reader/Writer の方の Dispose だけを呼べばOK
  • Close メソッドは呼ばなくてよい。(中で Dispose を読んでいるだけ)
  • Dispose を直接書くより、 using 構文を使うのが良い

きっかけ

C#でストリームを扱うときは

  • C# の Stream クラス の読み書きは Reader/Writer でする
  • Stream クラスは使い終わったら Dispose する
  • Reader/Writer も Dispose する必要がある

という感じですが、このあたりでいくつか気になる点があったので調べました。

なぜ Reader/Writer にも Dispose が存在するのか

ストリームは内部にファイルポインタなり、ソケットなどを持っているだろうから、Dispose必要というのはわかる。

では、Reader/Writer にもDisposeがあるのはなぜ?(何を解放しているのか?)

TextReader の場合

StreamReader の親である TextReader は何もしなくていいみたいで、空のメソッド。

protected virtual void Dispose(bool disposing)
{
}

StreamReader の場合

StreamReader になると、エンコーディングやバッファの情報を消している

if (!LeaveOpen && (_stream != null))
{
    _stream = null;
    _encoding = null;
    _decoder = null;
    _byteBuffer = null;
    _charBuffer = null;
    _charPos = 0;
    _charLen = 0;
    base.Dispose(disposing);
}

なるほど!読み書きのバッファなどを持っている場合、それも解放しないといけないってことですかね。

Reader/Writer の Dispose と Stream の Dispose 両方呼ぶ必要があるか

Reader/Writer の方だけでいいみたいです。
中のStreamも自動的にDisposeしてくれます。

ただし、Reader/Writer のコンストラクタ引数の leaveOpen を true にすることで、 Stream を解放しないようにもできます。

Close メソッドとは何なのか

内部で Dispose を呼び出しているだけなので、無視して大丈夫です。

using 構文について

usingで囲むと自分でDisposeを呼ぶ必要はなくなります。(using構文が内部でDisposeを呼んでくれます)
積極的に using で済ますようにしたほうが良さそうです。

using (var stream = ...)
using (var reader = new StreamReader(stream, ...))
{
    ...
}

// usingを抜けたら自動的に Dispose してくれる

(Marimoiroさんコメントありがとうございます)

参考リンク

参考リンク

3
2
4

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3
2