2009-10-30 10 views
10

複数のマルチイメージTIFFファイルを1つのマルチイメージTIFFファイルに結合していて、ソースTIFFファイルの削除に問題があるそれらにハンドルを保持し続けます。Image.FromFileを使用するとファイルのハンドルが解放されない

私はImage.FromFileを通じてTIFF画像を読んでいる:私は他のすべてのTIFF画像を同じように読み、そして得られたTIFF画像にそれらを追加し

Bitmap resultTiff = (Bitmap) Image.FromFile(strImageFile); 

た後。

私は参照を解放すると、ファイル結果として保存するには、このコードを使用し終わったら:

ep.Param[0] = new EncoderParameter(enc, (long) EncoderValue.Flush); 
resultTiff.SaveAdd(ep); 
resultTiff.Dispose(); 

を今の問題は、ファイル上のハンドルはまだが存在する(したがって、ファイルが削除できないことです)resultTiff.Dispose()コールの後にGC.Collect()と呼ぶ場合を除きます。

私はGCと呼ぶことで気分が良くないと思いますが、これを達成する他の方法はありますか?

答えて

17

を、それが開いているファイルハンドルを残し特徴Image.FromFileの問題を解決する最良の方法は、代わりにImage.FromStreamを使用することです。明示的な廃棄()、使用して()ステートメントを使用したり、ガベージコレクションが発生するまで、問題が解決しないヌルに値を設定する

using (FileStream fs = new FileStream(filePath, FileMode.Open, FileAccess.Read)) 
{ 
    using (Image original = Image.FromStream(fs)) 
    { 
     ... 

。ガベージコレクションを強制的に実行することは、一般的には悪い考えです。

+2

+1です。 'Image.FromFile'は必ずしも正確に正しいことをするわけではありません。手動でファイルストリームを開いてそこからビットマップを読み込んで置き換えることで、より柔軟に対応できます。 – stakx

+0

何らかの理由で 'FileStream'は私に同じ問題を与えていました。代わりに 'Image.FromStream(新しいMemoryStream(File.ReadAllBytes(path)))'を使いました。これはうまくいきました。 – William

1

あなたは試すことができます:

resultTiff = null; 
+0

あなたはこれを行う必要はありません - それは動作します。私は画像の1000をループにロードして処理した画像アプリを持っていました。ループ内に 'img = null'がなければ、非常に素早くOOMエラーが発生します。 – Pondidum

+0

@Pondium:私もその問題を抱えていました。 sidenoteとして、私はそれがメモリ不足のせいだけではなく、GDIハンドルの欠如によって引き起こされただけかもしれないと考えています。 – stakx

5

するか、試してみてください。

Using(Bitmap resultTiff = (Bitmap) Image.FromFile(strImageFile)) 
{ 
    ep.Param[0] = new EncoderParameter(enc, (long) EncoderValue.Flush); 
    resultTiff.SaveAdd(ep); 
} 
+1

'使用する 'は間違いなく推奨ですが、おそらくGoranの特定の問題は解決しません。この質問で与えられたコード例は、(例外的な状況では) 'Dispose'をすでに呼び出しています。 – LukeH

+0

ご回答いただきありがとうございます。ちょうど私がコードのどこかで不具合を起こしてしまったことが起こりました。そして、私が問題を解決したDisposeを使って解決しました。 最初のファイルに私が_appending_していたファイルへの参照を破棄していませんでした。私がこれを修正すると、すべてがうまくいっていた。この答えは – Goran

関連する問題