0

インスタンス化されたオブジェクトが破棄されるまで開いたままになるクラスを作成しようとしました。これは、プログラムの実行中に外部ソースがファイルを編集しないことが重要であるStreamWriterため、通常のイディオムを回避するためです(したがって)。 usingFileShare.Read

インスタンス化されると、ファイルはコンストラクターを介して正常に作成されます。メソッドの呼び出しWriteは実際には何も書き込まず、例外もスローしません。オブジェクトが破棄されると、デストラクタはの例外をスローしますが、sw.Close()はそうではありません。その理由がよくわかりません。Cannot access a closed file.BaseStreamnull

この質問は、いくぶん似たアプローチに従いますが、他のタイプのクラスです。したがって、このアプローチは機能するはずだと思いましたが、機能しない理由を特定できませんでした。

class SchemaWriter
{
    private StreamWriter sw;
    private string path;

    /// <summary>
    /// Creates an object to handle writing Schema.ini information
    /// </summary>
    /// <param name="Path">Path to place Schema.ini file in</param>
    public SchemaWriter(string Path)
    {
        path = Path;
        sw = new StreamWriter(File.Open(Path + "Schema.ini", FileMode.Create,
                              FileAccess.ReadWrite, FileShare.Read));
    }

    /// <summary>
    /// Writes Schema information about the supplied file name
    /// </summary>
    /// <param name="FileName">Name of file to write the Schema info about</param>
    public void Write(string FileName)
    {
        sw.WriteLine(String.Format(@"[{0}]", FileName));
        sw.WriteLine(@"Format=TabDelimited");
        sw.WriteLine();
    }

    /// <summary>
    /// Closes StreamWriter, deletes ini file
    /// </summary>
    ~SchemaWriter()
    {
        if(sw.BaseStream != null)
            sw.Close();
        File.Delete(path + @"Schema.ini");
    }
}
4

2 に答える 2

3

GCはすでにそれを主張しています(そしてそれを処分しました)。あなたがしなければならない唯一のことは、を実装することですIDisposable。以下をせよ:

class SchemaWriter : IDisposable
{
    private StreamWriter sw;

    public void Dispose()
    {
       sw.Dispose();
    }

    ...
}

これで、オブジェクトを次のように使用できます。

using(var writer = new SchemaWriter())
{
}

StreamWriterこれにより、オブジェクトの処理が完了するとすぐに閉じます。また、GCを使用しない場合は、GCがそのように感じたときにusing収集します。StreamWriter

于 2013-02-07T17:24:27.503 に答える
1

usingブロックを使用する理由の1つは、 StreamReaders/Writersがバッファリングされるため、書き込まれるバイトごとにハードドライブに再アクセスする必要がないことです。これは、を呼び出すまで、データが実際にディスクに出力されない場合があることを意味しますStreamWriter.Flush

それでもusingブロックを使用することをお勧めしますが、「開いたままにする」オーバーライドを使用するだけです。見る:

http://msdn.microsoft.com/en-us/library/gg712853.aspx

于 2013-02-07T17:09:55.523 に答える