3

あるファイルストリームからデータを読み取り、別のファイルストリームに書き込むクラスがあります。closeFiles()での処理が終了した後、ストリームを閉じることが心配です。

一方のストリームの破棄が例外をスローして、もう一方のストリームの破棄が呼び出されないようにする可能性をどのように処理しますか?

私は近くに電話して小川に処分するべきですか、それとも1つだけですか?

ストリームの破棄からエラーをキャッチし、lastOperation()に示すようにファイルの移動と削除を続行するとどうなりますか?

完璧な世界では、c ++スタイルの初期化リストでusingステートメントを使用したいのですが、c#ではそれが不可能であると確信しています。

編集:迅速な対応の人に感謝します。したがって、私がすべきことは、IDisposableから派生し、コンストラクターを変更して、次のような2つの破棄メソッドを追加することです。

    ~FileProcessor()
    {
        Dispose(true);
    }

    public void Dispose()
    {
        Dispose(true);
        GC.SuppressFinalize(this);
    }
    private void Dispose(bool disposing)
    {
        if (!this.disposed)
        {
            if (disposing)
            {
                sw.Flush();
            }
            closeFiles();
            disposed = true;
        }
    }

これは基本的に私がしていることです:

class FileProcessor
{
    private string in_filename;
    private string out_filename;
    private StreamReader sr;
    private StreamWriter sw;
    bool filesOpen = false;

    public FileProcessor(string filename)
    {
        in_filename = filename; 
        out_filename = filename + ".out";
        openFiles();
    }

    ~FileProcessor()
    {
        closeFiles();
    }

    private void openFiles()
    {
        sr = new StreamReader(in_filename);
        sw = new StreamWriter(out_filename);
        filesOpen = true;
    }

    private void closeFiles()
    {
        if (filesOpen)
        {
            sr.Close();
            sw.Close();
            sr.Dispose();
            sw.Dispose();
            filesOpen = false;
        }
    }

    /* various functions to read, process and write to the files */

    public void lastOperation()
    {
        closeFiles();
        File.Delete( in_filename );
        Directory.Move(out_filename, outdir + out_filename);
    }
}
4

4 に答える 4

3

IDisposableIDisposableオブジェクトをクラス内で使用している場合は、クラスにインターフェイスを実装させることをお勧めします。

次に、Dispose()実装で例外をスローしないようにする必要があります。あなたが処分するすべてのオブジェクトがこの保証をするならば、あなたのクライアントは安全です。

于 2010-11-29T10:20:03.087 に答える
3

FileProcessorクラスにデストラクタを含めることはできません。役に立たないが高価だ。

Dispose()closeFiles()を呼び出すための(そしてIDisposableインターフェースを実装する)必要があります。

そして、@ marceloが答えたように、Stream.Dispose()はスローすべきではありません。BCLクラスではこれを信頼できます。

ただし、最初のリーダー/ライターが開いたが、2番目のリーダー/ライターが失敗した場合は、各リーダー/ライターのnullを確認する必要があります。

if (sr != null) sr.Dispose();
if (sw != null) sw.Dispose();

filesOpen両方をカバーすることはできません。

于 2010-11-29T10:20:14.040 に答える
2

Disposeメソッドは例外をスローしないようにする必要があります。これに対するコード分析ツールの警告もあります。

于 2010-11-29T10:17:41.490 に答える
0

C#では、using存在します。usingステートメントに提供されるオブジェクトは、IDisposableインターフェースを実装する必要があります。このインターフェイスは、オブジェクトのリソースを解放するDisposeメソッドを提供します。

StreamReaderとStreamWriterがIDisposableを実装している場合は、それらをusingブロックに入れることができ、使い終わったらきれいに破棄されます。

using(var sr = new StreamReader(in_filename)) {
    // Perform reader actions
}
// Reader will now be disposed.
于 2010-11-29T10:18:58.217 に答える