回答:
はい、StreamReader
、StreamWriter
、BinaryReader
とBinaryWriter
お電話の際は、すべての近くに/その基礎となるストリームを処分しDispose
、それらに。彼らはしていないリーダ/ライタはかかわら収集ただのゴミである場合は、ストリームを処分-あなたはいつもできれで、リーダ/ライタを処分すべきであるusing
声明。(実際、これらのクラスにはファイナライザがありません。
個人的には、ストリームのusingステートメントも使用することを好みます。using
中括弧なしでステートメントを入れ子にすることができます。
using (Stream stream = ...)
using (StreamReader reader = new StreamReader(stream, Encoding.Whatever))
{
}
using
ストリームのステートメントは多少冗長ですが(StreamReader
コンストラクターが例外をスローしない限り)、私はそれを排除StreamReader
し、後でストリームを直接使用する場合は、すでに適切な処分をしているので、ベストプラクティスを検討しますセマンティクス。
CA2202 : Microsoft.Usage : Object 'stream' can be disposed more than once in method '...'. To avoid generating a System.ObjectDisposedException you should not call Dispose more than one time on an object.
それは無視されるべきですか?今のところ例外はありませんでした...
StreamReader
。警告ルックスはのためのドキュメントことを考えると、私におかしなIDisposable.Dispose
明示的状態:「オブジェクトのDisposeメソッドは、オブジェクトが最初のものの後にすべての呼び出しを無視しなければならない、複数回呼び出された場合、そのDisposeメソッドがある場合、オブジェクトが例外をスローしてはいけません。複数回呼び出されました。」
これは古いものですが、今日は同じようなことをしたいと思い、状況が変わったことがわかりました。.net 4.5以来、leaveOpen
議論があります:
public StreamReader( Stream stream, Encoding encoding, bool detectEncodingFromByteOrderMarks, int bufferSize, bool leaveOpen )
唯一の問題は、他のパラメーターに何を設定するかが完全に明らかではないことです。ここにいくつかの助けがあります:
StreamReaderコンストラクター(ストリーム)のmsdnページから:
このコンストラクターは、エンコーディングをUTF8Encoding、ストリームパラメーターを使用するBaseStreamプロパティ、および内部バッファーサイズを1024バイトに初期化します。
それだけで、ソースコードdetectEncodingFromByteOrderMarks
による判断はtrue
public StreamReader(Stream stream)
: this(stream, true) {
}
public StreamReader(Stream stream, bool detectEncodingFromByteOrderMarks)
: this(stream, Encoding.UTF8, detectEncodingFromByteOrderMarks, DefaultBufferSize) {
}
これらのデフォルトの一部が公開されている場合、または引数がオプションであり、必要なものだけを指定できるようになっていると便利です。
using (var streamReader = new StreamReader(myStream, Encoding.UTF8, true, 1024, true))
はい、そうです。これは、Reflectorを使用して実装を確認することで確認できます。
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;
this.encoding = null;
this.decoder = null;
this.byteBuffer = null;
this.charBuffer = null;
this.charPos = 0;
this.charLen = 0;
base.Dispose(disposing);
}
}
}
6年遅れますが、多分これは誰かを助けるかもしれません。
StreamReaderは、破棄されるときに接続を閉じます。ただし、StreamReader / StreamWriterで「using(Stream stream = ...){...}」を使用すると、Streamが2回破棄される可能性があります。(1)StreamReaderオブジェクトが破棄されるとき(2)およびStream usingブロックが破棄されるとき閉じます。これにより、VSのコード分析を実行すると、CA2202警告が表示されます。
CA2202ページから直接取得した別のソリューションは、try / finallyブロックを使用することです。正しくセットアップしてください。これにより、接続が一度だけ閉じられます。
マイクロソフトはCA2202の下部近くで、以下を使用することをお勧めします。
Stream stream = null;
try
{
stream = new FileStream("file.txt", FileMode.OpenOrCreate);
using (StreamWriter writer = new StreamWriter(stream))
{
stream = null;
// Use the writer object...
}
}
finally
{
if(stream != null)
stream.Dispose();
}
の代わりに...
// Generates a CA2202 warning
using (Stream stream = new FileStream("file.txt", FileMode.Open))
using (XmlReader reader = new XmlReader (stream))
{
// Use the reader object...
}
必要な場合にこれを修正する簡単な方法は、StreamWriterクラスのDisposeメソッドをオーバーライドすることです。それを行う方法のコードについては、こちらの投稿を参照してください。