1. ホーム
  2. c#

[解決済み] System.IO.IOException。System.IO.Path.GetTempFileName() で "The file exists" - 解決?

2023-02-23 19:50:26

質問

ある顧客が、私の製品を使おうとすると例外が発生しました。私は発生した例外のコールスタックを取得し、そのトップは次のとおりです。

at System.IO.__Error.WinIOError(Int32 errorCode, String maybeFullPath)
   at System.IO.__Error.WinIOError()
   at System.IO.Path.GetTempFileName()
   at System.Windows.Input.Cursor.LoadFromStream(Stream cursorStream)
   at System.Windows.Input.Cursor..ctor(Stream cursorStream)

これをググってみると、たくさんの ブログ記事 によると、この例外は %TEMP% フォルダに 65535 個以上の一時ファイルがある場合に発生し、解決策は単に古い一時ファイルを削除することであるとのことです。もし、GetTempFileName を頻繁に呼び出すような他のソフトウェアを定期的に実行していたら、問題は何度も再発するのではないでしょうか?

プログラム的に %TEMP% フォルダをクリアすることはできません。それは何らかの形で他のものを損傷する可能性があるからです。また、私ではなく WPF コードがそれを呼び出しているため、GetTempFileName の呼び出し (と代わりに自分の一時フォルダを使用) を避けることはできません。

これに対する恒久的な解決策はあるでしょうか。

アップデイト : TEMP% フォルダがログファイルで溢れる問題は、私自身のコードが原因ではなく、顧客のマシン上の他のサードパーティアプリケーションが原因である必要があることを確認しました。また、実装を調べてみたところ Cursor.LoadFromStream の実装も調べてみましたが、確かにそれは誤りではありません。それは一時ファイルを生成しますが、それを削除するには finally ブロック内で削除しています。

どのように解決するのですか?

前回のコメントで述べたように、これを行う唯一の安全な方法は、ファイルを削除してもう一度試してほしいかどうかをユーザーに尋ねることだと思います。それは 必須 この方法は、ユーザー自身の危険にさらされています。私の頭の中では、そのようなものです。

public Stream GetStream(Stream cursorStream)
{
    try
    {
       //getting stream
    }
    catch(IOE)
    {
        MessageBox.Show(this, "Unable to get stream, your temporary
                              folder may be full, do you want to try deleting 
                                some and try again?");
         if(yes)
         try
         {
             //delete and try again
             return GetStream(cursorStream);
         }
         catch(IOE)
          {
                //no luck
           }
          else
              return null;
    }

}

可能性があることを確認するためのオプションのチェックです。

Directory.EnumerateFiles(Path.GetTempPath(), "*", SearchOption.TopLevelOnly)
  .Count() == ushort.MaxValue;