スポンサーサイト

上記の広告は1ヶ月以上更新のないブログに表示されています。
新しい記事を書く事で広告が消せます。
Prev.    Category    Next 

C# でファイル開くなら using を使おう

C# でファイルを開くときなどに using を使っていますか?
紛らわしいのですが、 using といっても名前空間で使用するものとは別ものです。 今回は using の使い方と何故使うべきなのかについて説明したいと思います。

using を使わない場合

ファイルオープンの問題点

あるファイルに書き込みを行い、次にそれを読み取る処理を考えます。
 {
     StreamWriter sw = new StreamWriter("TestFile.txt");
     // ファイルへの書き込み
     sw.WriteLine("Hello World!");
 }
 // ファイルの読込
 StreamReader sr = new StreamReader("TestFile.txt");
ファイルへの書き込みを行うオブジェクト sw はブロックを抜けると、 必要がなくなり解放されます。この時ファイルのクローズが行われます。
ただし、解放の後処理をガベージコレクション(GC)任せにしていると、 ファイルが閉じられる前にアクセスして、不測の結果を招きかねません。


そこで、今度はちゃんとファイルのクローズも呼び出してみます。
C# では IO ストリーム系のクラスはファイルのクローズ Close() とリソースの解放 Dispose() が同じ処理です。 ここではクローズの処理として Dispose() を使用します。
 {
     StreamWriter sw = new StreamWriter("TestFile.txt");
     // ファイルへの書き込み
     sw.WriteLine("Hello World!");
 
     sw.Dispose();               // sw.Close() と同じ
 }

例外への対応

先ほどの対応で OK としたいところですが、 書き込みの処理が複雑になってくると例外の発生を考慮する必要がでてきます。
途中の処理で例外が発生して、抜けることになっても Dispose() は呼び出さないといけません。

これを try, catch, finally で書くと次のようになります。
 StreamWriter sw = new StreamWriter("TestFile.txt");
 try
 {
     // ファイルへの書き込み
     sw.WriteLine("Hello World!");
 }
 catch( Exception e )
 {
     // 例外処理
 }
 finally
 {
     // 常に行う終了処理
     sw.Dispose();
 }
しかし、これでは記述が若干面倒です。 これを簡易的に記述するのが using です。

using の使用

using を使った記述

using は次のように使用します。
 using (IDisposableを継承したオブジェクト)
 {
     // 処理
 }
 // ブロックを抜けるときにオブジェクトの Dispose() メソッドを呼び出す。
先ほどの記述を using を使って書きなおしてみます。 例外で記述したのと比べると大分簡単に書けるようになります。
 using (StreamWriter sw = new StreamWriter("TestFile.txt"));
 {
     // ファイルへの書き込み
     sw.WriteLine("Hello World!");
 }

何故、 using を使うのか

実際には何度もアクセスするということがなければ、 ファイルのクローズも GC まかせでも問題はないかもしれません。
しかし、修正等でいざアクセスすることになったとき、 GC まかせなので、 環境によって出たり出なかったりする たちの悪いバグ になる可能性があります。

using を使うのは、 後処理のタイミングを管理し、 なおかつ例外の発生にも対処ためです。

using を使う対象

これまでファイルを開くときに using を使うと書いてきましたが、 この using は何にでも使えるわけではありません。
foreach を使えるのが IEnumerable インターフェースを継承したクラスであるように、 using を使えるのは IDisposable インターフェースを継承したクラスです。 どういったものが IDisposable を継承しているかというと ファイルや C++ 由来のものといったアンマネージリソースを扱っているクラスが多いです。

これは逆にいうと IDisposable の継承は後処理のタイミング管理が必要というサインです。 IDisposable を継承したクラスでは必ず using を使うというように心がけた方がいいでしょう。

using 使用時の注意点

using を使った方がいいと言いましたが、 無理して using を使って using のブロックが異常に長くなるのは、 コード的に良くありません。
そういった場合は using で開いた後のオブジェクト(サンプルでは sw) をメソッドの引数として渡すなどして、処理を分割していきます。

しかし、それでは上手く行かず、クラスのメンバーとして IDisposable 継承したクラスのオブジェクトを持ちたい場合もあります。 そういう時はそのクラスも IDisposable を継承し、後処理を行うようにした方がいいでしょう。 そして、そのクラスをインスタンス化する時に using を使うようにします。

IDisposable インターフェースの実装方法については以前の記事をご覧ください。 ちなみに、今回の記事は上記の記事で書いてあったものを 検索と広告対策で抜粋、加筆修正して別記事としたものです。



関連記事
スポンサーサイト
Prev.    Category    Next 

Facebook コメント


コメント

コメントの投稿

Font & Icon
非公開コメント

このページをシェア
アクセスカウンター
アクセスランキング
[ジャンルランキング]
コンピュータ
9位
アクセスランキングを見る>>

[サブジャンルランキング]
プログラミング
3位
アクセスランキングを見る>>
カレンダー(アーカイブ)
プルダウン 降順 昇順 年別

09月 | 2017年10月 | 11月
1 2 3 4 5 6 7
8 9 10 11 12 13 14
15 16 17 18 19 20 21
22 23 24 25 26 27 28
29 30 31 - - - -


はてな新着記事
はてな人気記事
ブロとも申請フォーム
プロフィール

yohshiy

Author:yohshiy
職業プログラマー。
仕事は主に C++ ですが、軽い言語マニアなので、色々使っています。

はてブ:yohshiy のブックマーク
Twitter:@yohshiy

サイト紹介
プログラミング好きのブログです。プログラミング関連の話題や公開ソフトの開発記などを雑多に書いてます。ただ、たまに英語やネット系の話になることも。
上記広告は1ヶ月以上更新のないブログに表示されています。新しい記事を書くことで広告を消せます。