C# 非管理リソースの開放 (一時ファイル作成後の後始末について)
リソースの開放はIDisposableインターフェースを実装して,開放処理を記述します.
これについては以下の記事がとてもわかり易いです.
さて,この記事では「非管理リソースの開放」について書きます.
例えば,Path.GetTempFileName()
メソッドで一時ファイルを作成したとします.
このメソッドはサイズ0バイトとのファイルを(Windowsでは)C:\Users\{User name}\AppData\Local\Temp
フォルダ内に生成します.
この一時ファイルに保存したいデータを書き込んだりして使います.
この一時ファイルですが,アプリケーションの終了時に自動的に削除されるわけではなく,残り続けます. ですので,利用し終わったら適切に削除する必要があります.
この一時ファイルは.NET Frameworkの管理外のため,非管理リソースとなります. このような非管理リソースを開放するには,一例として以下のようにすることができます.
一時ファイルを生成するためのクラスを作成し,このクラスにIDisposableを実装して,非管理リソースである一時ファイルが削除されるようにしています.
public class TemporaryFile : IDisposable { private string fullName = Path.GetTempFileName(); private bool disposedValue = false; public string FullName { get => fullName; } public void Dispose() { //GC前にプログラム的にリソースを破棄するので //管理,非管理リソース両方が破棄されるようにする Dispose(true); GC.SuppressFinalize(this);//破棄処理は完了しているのでGC不要の合図 } protected virtual void Dispose(bool disposing) { if (disposedValue) { return; } if (disposing) { //管理リソースの破棄処理 } //非管理リソースの破棄処理 try { File.Delete(this.fullName); } catch { throw; } disposedValue = true; } ~TemporaryFile() { //GC時に実行されるデストラクタでは非管理リソースの削除のみ Dispose(false); } }
ここで使用しているのが,Disposeパターンです.
使い方
using (var tempFile = new TemporaryFile()) { File.WriteAllText(tempFile.FullName,"hello"); //.... }
using句を抜けるときにtempFileオブジェクトがDisposeされ,その際に一時ファイルがDeleteされます.