77

POSIXシステムでは、rename(2)は、宛先ファイルが存在する場合、およびアクセス許可が許可されている場合の上書きを含む、アトミックな名前変更操作を提供します。

Windowsで同じセマンティクスを取得する方法はありますか?VistaおよびServer2008でのMoveFileTransacted()については知っていますが、Win2k以降をサポートするにはこれが必要です。

ここでのキーワードはアトミックです...ソリューションは、操作を一貫性のない状態のままにするような方法で失敗してはなりません。

これはwin32では不可能だと多くの人が言うのを見てきましたが、本当にそうですか?

可能であれば、信頼できる引用を提供してください。

4

8 に答える 8

40

ReplaceFile()Win32 で参照( http://research.microsoft.com/pubs/64525/tr-2006-45.pdf )

于 2010-03-03T01:56:24.173 に答える
20

Win32 は、アトミック ファイル メタデータ操作を保証しません。引用を提供したいのですが、何もありません。書面または文書化された保証がないという事実は、それだけの意味があります。

これをサポートするには、独自のルーチンを作成する必要があります。残念ながら、win32 がこのレベルのサービスを提供することを期待することはできません。単純に、win32 はそのために設計されていません。

于 2008-10-03T15:55:50.317 に答える
10

Windows ではまだ rename() 呼び出しがありますが、使用しているファイルシステムを知らなければ、必要な保証を行うことはできないと思います。たとえば、FAT を使用している場合は保証されません。

ただし、MoveFileEx を使用して、MOVEFILE_REPLACE_EXISTING および MOVEFILE_WRITE_THROUGH オプションを使用することはできます。後者については、MSDN に次の説明があります。

この値を設定すると、コピーおよび削除操作として実行される移動が、関数が戻る前にディスクにフラッシュされることが保証されます。フラッシュは、コピー操作の最後に発生します。

それが名前変更操作と必ずしも同じではないことはわかっていますが、それが得られる最善の保証であると思います.ファイルの移動に対してそれを行う場合は、より簡単な名前変更を行う必要があります.

于 2008-10-03T15:39:18.137 に答える
6

MSDN のドキュメントでは、アトミックな API とそうでない API を明確に述べるのを避けていますが、Niall Douglas はCppcon 2015 の講演で、唯一のアトミック関数は

SetFileInformationByHandle

trueにFILE_RENAME_INFO.ReplaceIfExists設定します。Windows Vista / 2008 Server 以降で利用できます。

Niall は非常に複雑なLLFIO ライブラリReplaceFileの作成者であり、ファイル システムの競合状態の専門家でもあります。そのため、アトミック性が重要なアルゴリズムを作成している場合は、後悔するよりも安全であり、.説明には、アトミックではないと記載されています。

于 2019-08-05T12:13:56.733 に答える
0

std::renameがあり、 C++17 std::filesystem::renameから始まります。宛先が次の場合に何が起こるかは未定ですstd::rename:

new_filename が存在する場合、動作は実装定義です。

ただし、既存のファイルをアトミックに置き換えるには、 POSIX renameが必要です。

この rename() 関数は、ISO C 標準で定義されている通常のファイルと同等です。ここに含めることで、その定義が拡張され、ディレクトリに対するアクションが含まれるようになり、新しいパラメーターが既に存在するファイルを指定した場合の動作が指定されます。その仕様では、関数のアクションがアトミックである必要があります。

ありがたいことに、std::filesystem::renamePOSIX と同じように動作する必要があります。

old_p で識別されるファイルシステム オブジェクトを、POSIX rename によるかのように new_p に移動または名前変更します。

ただし、デバッグしようとするとstd::filesystem::rename、VS2019 (2020 年 3 月現在) で実装されているように、単純にMoveFileExを呼び出しているように見えますが、これは場合によってはアトミックではありません。したがって、おそらく、その実装のすべてのバグが修正されたときに、ポータブル アトミック が表示されるでしょうstd::filesystem::rename

于 2020-04-01T04:22:26.047 に答える