このサイトの.NET Tipsでは、分かりやすさを優先しているため、紹介している多くのコードで例外処理を省略しています。特にDispose、Closeメソッドを確実に呼び出さなければならないケースで問題となる可能性があります。
まずは次のコードをご覧ください。これは、シフトJISのテキストファイルを読み込むコードです(詳しくは、こちらで説明しています)。
Dim sr As New System.IO.StreamReader("C:\test.txt", _ System.Text.Encoding.GetEncoding(932)) Dim s As String = sr.ReadToEnd() sr.Close() Console.WriteLine(s)
System.IO.StreamReader sr = new System.IO.StreamReader(@"C:\test.txt", System.Text.Encoding.GetEncoding(932)); string s = sr.ReadToEnd(); sr.Close(); Console.WriteLine(s);
上記のコードには問題があります。ReadToEndメソッドに失敗して例外がスローされた場合、Closeメソッドが呼び出されません。Closeメソッドはデータをファイルに書き込み、ファイルのロックを解除し、リソースを解放するために呼び出される必要があります。StreamReaderオブジェクトをこれ以上使用しないのであれば、Closeメソッドを呼び出すべきです。
このように、使用後にCloseやDisposeメソッドを呼び出す必要があるクラスは多く存在します(詳しくは、MSDNでご確認ください)。ここでは、確実にCloseやDisposeメソッドを呼び出す方法を紹介します。
まずはtry...finallyステートメントを使用する方法を紹介します。上記のコードを書き換えてCloseメソッドが確実に呼び出されるようにするには、次のようにします。finallyステートメントにCloseメソッドを記述します。
Dim sr As System.IO.StreamReader = Nothing Try sr = New System.IO.StreamReader( _ "C:\test.txt", System.Text.Encoding.GetEncoding(932)) Dim s As String = sr.ReadToEnd() Console.WriteLine(s) Finally If Not (sr Is Nothing) Then sr.Close() End If End Try
System.IO.StreamReader sr = null; try { sr = new System.IO.StreamReader(@"C:\test.txt", System.Text.Encoding.GetEncoding(932)); string s = sr.ReadToEnd(); Console.WriteLine(s); } finally { if (sr != null) sr.Close(); }
C#を使用しているか、.NET Framework 2.0以降であれば、usingステートメントを使用することができます。ほとんどのケースで、この方法の方がよりシンプルです。ただし、.NET Framework 1.1以前でVB.NETを使用しているならば、この方法は不可です。usingステートメントでは、IDisposeインターフェイスが実装されているクラスのDisposeメソッドが呼び出されることを保障します。
Dim s As String Using sr As New System.IO.StreamReader( _ "C:\test.txt", System.Text.Encoding.GetEncoding(932)) s = sr.ReadToEnd() End Using Console.WriteLine(s)
string s = ""; using (System.IO.StreamReader sr = new System.IO.StreamReader(@"C:\test.txt", System.Text.Encoding.GetEncoding(932))) { s = sr.ReadToEnd(); } Console.WriteLine(s);