2

ファイルハンドルにデータを書き込んでいるとしましょう:

hFile = CreateFile(filename, GENERICREAD | GENERICWRITE, 0, null, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, 0);
//[snip error check]
try
{
   if (!WriteFile(hFile, buffer, count, ref bytesWritten, null))
       throw new Win32Exception(GetLastError());
}
finally
{
   CloseHandle();
}

データの書き込みに失敗した場合、ハンドルを閉じたときにファイルを削除したい。つまり、ファイルを「un-CreatFile'd」にしたい。


私は明らかなことを試しました。問題があった場合はファイルを削除してください:

hFile = CreateFile(filename, GENERICREAD | GENERICWRITE, 0, null, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, 0);
//[snip error check]
try
{
   try
   {
      if (!WriteFile(hFile, buffer, count, ref bytesWritten, null))
          throw new Win32Exception(GetLastError());
   }
   finally
   {
      CloseHandle();
   }
}
catch
{
   DeleteFile(filename);
   throw;
}

このアプローチには 2 つの問題があります。

  1. ファイルを閉じた後、削除する前に誰かがファイルを開くことができるという競合状態があります
  2. ファイルを作成する権限はあるかもしれませんが、削除する権限はありません。

私が望むのは、遡及的に指定する方法です:

FILE_FLAG_DELETE_ON_CLOSE: ファイルは、すべてのハンドルが閉じられた直後に削除されます。これには、指定されたハンドルと、開いているハンドルまたは重複しているハンドルが含まれます。

私が開いているファイルに。

ファイルを作成しました!確かに私はそれを作成することができます! 事前にフラグを指定するのを忘れたからですか?

4

3 に答える 3

5

SetFileInformationByHandleWindows Vista 以降では、 と を使用してこれを行うことができますFILE_DISPOSITION_INFO

于 2013-01-28T22:58:09.530 に答える
5

Windows のすべてのバージョンで、次のことができます。

  1. FILE_SHARE_DELETEファイルを最初に開くときに指定します。
  2. 指定して、もう一度開きますFILE_FLAG_DELETE_ON_CLOSE
  3. 2 番目のハンドルを閉じます。
  4. すべてのハンドルが閉じられると、ファイルは削除されます。

これについては、次FILE_FLAG_DELETE_ON_CLOSEのドキュメントの説明で説明されていCreateFileます。

ファイルは、そのすべてのハンドルが閉じられた直後に削除されます。これには、指定されたハンドルと、開いているハンドルまたは重複しているハンドルが含まれます。ファイルへの既存の開いているハンドルがある場合、それらがすべてFILE_SHARE_DELETE共有モードで開かれていない限り、呼び出しは失敗します。


自動削除が十分でない場合は、トランザクション NTFS を調べて、ファイルの作成とすべての書き込みをトランザクションに入れ、必要に応じてロールバックすることができます。

于 2013-01-28T23:03:11.533 に答える
1

Windows 2003 サーバーまたは Vista 以降を使用している場合、探しているのはReOpenFile()です。再オープンされたハンドルに新しい「フラグ」パラメーターを指定できます。残念ながら、XP では利用できないようです。

于 2013-01-28T22:58:41.983 に答える