メソッドにストリームを送信して書き込みを行い、それらのメソッドではバイナリリーダー/ wrtierを使用しています。リーダー/ライターがusing
によって破棄された場合、または参照されていない場合、ストリームも閉じられますか??
BinaryReader/Writerを送信しますが、StreamReaderも使用します(たぶんそれを回避する必要があります。GetLineとReadLineにのみ使用しています)。ライター/リーダーが閉じられるたびにストリームを閉じる場合、これは非常に面倒です。
はい、StreamReader
、StreamWriter
、BinaryReader
、およびBinaryWriter
はすべて、Dispose
を呼び出すときに、基になるストリームを閉じたり破棄したりします。 do n'tリーダー/ライターがガベージコレクトされている場合はストリームを破棄します-リーダー/ライターは常にusing
ステートメントで破棄する必要があります。 (実際、これらのクラスにはファイナライザーはありませんし、持っているべきでもありません。)
個人的には、ストリームのusingステートメントも使用することを好みます。中括弧なしでusing
ステートメントをきれいにネストできます。
using (Stream stream = ...)
using (StreamReader reader = new StreamReader(stream, Encoding.Whatever))
{
}
ストリームのusing
ステートメントは多少冗長ですが(StreamReader
コンストラクターが例外をスローしない限り)、StreamReader
と後日直接ストリームを使用するだけで、適切な廃棄セマンティクスが既に得られます。
これは古いものですが、今日は似たようなことをしたかったため、状況が変わったことがわかりました。 .net 4.5以降、leaveOpen
引数があります。
public StreamReader( Stream stream, Encoding encoding, bool detectEncodingFromByteOrderMarks, int bufferSize, bool leaveOpen )
唯一の問題は、他のパラメーターに何を設定するかが完全に明らかではないことです。ヘルプがあります:
FrommsdnページStreamReaderコンストラクター(ストリーム)の場合:
このコンストラクターは、エンコードをUTF8Encodingに初期化し、streamパラメーターを使用してBaseStreamプロパティを初期化し、内部バッファーサイズを1024バイトに初期化します。
ソースコードで判断されるdetectEncodingFromByteOrderMarks
はtrue
のままです
public StreamReader(Stream stream)
: this(stream, true) {
}
public StreamReader(Stream stream, bool detectEncodingFromByteOrderMarks)
: this(stream, Encoding.UTF8, detectEncodingFromByteOrderMarks, DefaultBufferSize) {
}
これらのデフォルトのいくつかが公開されている場合、または引数がオプションであるため、必要なものを指定することができればいいでしょう。
はい、そうです。 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で「(stream stream = ...){...}」を使用すると、Streamが2回破棄される可能性があります。(1)StreamReaderオブジェクトが破棄されるとき(2)およびブロックを使用するストリーム閉じます。これにより、VSのコード分析の実行時にCA2202警告が発生します。
CA2202 ページから直接取得した別のソリューションは、try/finallyブロックを使用することです。正しくセットアップすると、接続は一度だけ閉じられます。
CA2202 の下部近くで、Microsoftは次の使用を推奨しています。
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...
}
はい。 Dispose()onおよびIDisposable( "using"を実行)を呼び出すと、オブジェクトはすべてのリソースをクリーンアップする必要があります。これには、ファイル記述子をフラッシュおよびクローズするストリームが含まれます。
あなたの場合、他のメソッドに渡す場合は、それらのメソッドがusingブロックで読み取り/書き込みを行わないようにする必要があります。
必要に応じてこれを修正する簡単な方法は、StreamWriterクラスのDisposeメソッドをオーバーライドすることです。それを行う方法のコードについては、私の投稿を参照してください: