2004年02月02日
川俣晶の縁側ソフトウェア技術雑記total 13552 count

「System.IO.IOException: ディスクに十分な空き領域がありません」のあとで永遠にハンドルをクローズできない問題についてのメモ

Written By: 川俣 晶連絡先

 ほとんど他人が読む価値がないかも知れない覚え書き的文章です。

 昔、GDNJのメーリングリストに書いた件をもうちょっと詳しく調べてしまいました。

 .NET Framework 1.1のFileStreamクラスや、最終的にそれを呼び出してファイルに書き込む場合、書き込み中にディスクの残り容量が尽きると、そのファイルをクローズできない問題。つまり、ファイルが開いたままになり、削除もできない問題です。

 ちょっと古いかも知れないけど、SSCLI(sscli2002101)のソースでFileStreamクラスのソースを追いかけてみました。これと同じ実装が行われていると仮定すると、すっきりと現象の説明が付きます。

 その結果分かったこと。

  • デストラクタはDisposeを呼んでいる
  • CloseはDisposeを呼んでいる
  • DisposeはFlush()を呼び出した後で、内部的なハンドルをクローズしている
  • Flushは書き込みのバッファに残ったデータを書き込もうとする

 以上のことから、Closeを呼び出したとしても、ハンドルを閉じる前にバッファの中身を書き込もうとしてそこで例外が起きてメソッドが中断され、ハンドルはクローズされないことになります。Closeのかわりにデストラクタを使っても、Disposeを使っても結果は同じになります。

 また、ハンドルを取り出して、それをWin32 APIのCloseHandleで強制クローズしようとしても上手く行きません。その理由は、以下の事実から容易に説明がつきます。

  • HandleプロパティはFlush()を呼び出している

 これらの挙動は、通常ケースでは妥当なものだと思います。しかし、ディスク残り容量ゼロという異常ケースでは、不適切な感があります。

2004年3月17日追記 §

 この問題に関する話題がC#のメーリングリストで出ました。これを回避する方法として、[CS:06118] Re: ファイル書き込みで容量オーバー時の処理方法にて内藤雅章さんが1つの方法を提案しました。

 メーリングリストのアーカイブにリンクしようと思いましたが、どうも古いメッセージは呼び出せるものの、最近のメッセージが呼び出せなかったので、要旨を以下にまとめます。

  • Write() の前に SetLength() する。つまり、実データを書き込む前に、それを書き込むために必要なサイズまで、ファイルのサイズを拡張する
  • ディスクが溢れる場合、SetLength() で例外が発生するが、その後Close()を正常に終了でき、ファイルが閉じる (バッファ内にファイルが残っていないので、それを書き込もうとする動作が起こらないと推測)

 メーリングリストでは、このあと、マルチスレッドで実行する場合など、この方法で上手く行かないケースの話題が続いています。

2004年3月20日追記 §

 渋木さんが、この問題を補完する作業を開始されました。

 Win32File - System.IO.FileStream 補完計画

2004年3月29日追記 §

 菊池和彦さんが、別の解決策を提案されました。

 System.IO.FileStream がDiskFull にぶつかると Close 不能になる問題に対する邪悪な解答

 リフレクションを使ってprivateなメンバを直接書き換えることで、バッファが空であると認識させます。例外ハンドラ内だけで対処できるのですっきりする反面、ドキュメント化されていないメンバに依存するため、将来のバージョンでは動作しない可能性があります。

2005年12月2日追記 §

 ホットフィックスが提供されているようです。

 FIX: .NET Framework 1.1 の十分な領域があるディスクのファイルにアクセスするために、 StreamWriter.Flush ()メソッドまたは StreamWriter.Close ()メソッドを使用すると、例外エラー メッセージを表示します。

Facebook

トラックバック一覧

2004年03月24日(センチメンタルに) ああ美しきかな、C#によるファイル読み込み処理ソースFrom: 冒険! オータム マガジン

疲れ果ててセンチメンタルになっているのか、今日は当たり前のものを見ても心がジーンとなります。 今開発中のソフトのソリューションをVisual Studio 2003で開いた瞬間、こんなメソッドのソー 続きを読む

キーワード【 川俣晶の縁側ソフトウェア技術雑記
【技術雑記】の次のコンテンツ
2004年
02月
13日
静的ウェブページでのTrackBack受信
3days 0 count
total 3548 count
【技術雑記】の前のコンテンツ
2004年
01月
30日
プチ ソフト冒険記・Adobe GoLive CS こんなソフトまで、いきなりXML文書が開けてしまう?
3days 0 count
total 2859 count

このコンテンツを書いた川俣 晶へメッセージを送る

[メッセージ送信フォームを利用する]

メッセージ送信フォームを利用することで、川俣 晶に対してメッセージを送ることができます。

この機能は、100%確実に川俣 晶へメッセージを伝達するものではなく、また、確実に川俣 晶よりの返事を得られるものではないことにご注意ください。

このコンテンツへトラックバックするためのURL

http://mag.autumn.org/tb.aspx/20040202140342
サイトの表紙【技術雑記】の表紙【技術雑記】のコンテンツ全リスト 【技術雑記】の入手全リスト 【技術雑記】のRSS1.0形式の情報このサイトの全キーワードリスト 印刷用ページ

管理者: 川俣 晶連絡先

Powered by MagSite2 Version 0.36 (Alpha-Test) Copyright (c) 2004-2021 Pie Dey.Co.,Ltd.