POSIXシステムでは、rename(2)はアトミックな名前変更操作を提供します。これには、宛先ファイルが存在する場合、および権限が許可されている場合、宛先ファイルの上書きが含まれます。
Windowsで同じセマンティクスを取得する方法はありますか? VistaとServer 2008でのMoveFileTransacted()については知っていますが、Win2k以降をサポートするにはこれが必要です。
ここでのキーワードはatomic ...ソリューションは、操作が一貫性のない状態のままになるような方法で失敗してはなりません。
多くの人がこれはwin32では不可能だと言っているのを見てきましたが、私はあなたに尋ねます、それは本当にですか?
可能であれば、信頼できる引用を提供してください。
Win32は、アトミックファイルのメタデータ操作を保証しません。私は引用を提供しますが、何もありません-書面または文書化された保証がないという事実は、同じくらい意味があります。
これをサポートするには、独自のルーチンを作成する必要があります。残念ですが、win32がこのレベルのサービスを提供することは期待できません。単にそのために設計されたわけではありません。
Win32のReplaceFile()
を参照してください( http://research.Microsoft.com/pubs/64525/tr-2006-45.pdf )
Windows VistaおよびWindows Server 2008では、アトミック移動機能が追加されました-MoveFileTransacted()
残念ながら、これは古いバージョンのWindowsでは役に立ちません。
windowsではまだrename()呼び出しがありますが、使用しているファイルシステムがわからなければ、必要な保証はできないと思います。たとえば、FATを使用している場合は保証されません。
ただし、MoveFileExを使用して、MOVEFILE_REPLACE_EXISTINGおよびMOVEFILE_WRITE_THROUGHオプションを使用できます。後者はMSDNで次のように説明されています。
この値を設定すると、コピーおよび削除操作として実行された移動が、関数が戻る前にディスクにフラッシュされることが保証されます。フラッシュは、コピー操作の最後に発生します。
名前変更操作と必ずしも同じではないことは知っていますが、ファイルの移動でそれを行う場合は、より簡単な名前変更を行う必要があります。
Windows 10 1607以降、NTFSはアトミックな置き換えの名前変更操作をサポートしています。これを行うには、NtSetInformationFile(...、FileRenameInformationEx、...)を呼び出し、FILE_RENAME_POSIX_SEMANTICSフラグを指定します。または、Win32で同等にSetFileInformationByHandle(...、FileRenameInfoEx、...)を呼び出して、FILE_RENAME_FLAG_POSIX_SEMANTICSフラグを指定します。
かなりの数の回答ですが、期待していたものではありません... MoveFileはアトミックである可能性がある(-===-)星が整列し、フラグが使用され、ファイルシステムはソースとターゲットで同じでした。そうでない場合、操作は[Copy-> Delete] Fileにフォールバックします。
とすれば;また、MoveFile(アトミックな場合)がファイル情報を設定するだけであることも理解していました。これは、ここでも実行できます setfileinfobyhandle 。
誰かが " Racing the Filesystem "と呼ばれる講演を行いましたが、これについてさらに深く掘り下げています。 (下の約3分の3は、原子名の変更について話します)
MSDNのドキュメントでは、どのAPIがアトミックであり、どれがアトミックでないかを明確に示すことを避けていますが、Niall Douglasは Cppcon 2015の講演 で、唯一のアトミック関数は
FILE_RENAME_INFO.ReplaceIfExists
をtrueに設定します。 Windows Vista/2008 Server以降で利用できます。
Niallは非常に複雑な LLFIOライブラリ の作成者であり、ファイルシステムの競合状態の専門家であるため、原子性が重要なアルゴリズムを作成している場合は、申し訳ありませんが提案された方法を使用するよりも安全であると考えていますReplaceFile
の説明にアトミックではないと記載されていなくても機能します。