web-dev-qa-db-fra.com

Un changement de nom de fichier atomique (avec écrasement) est-il possible sous Windows?

Sur les systèmes POSIX, rename (2) fournit une opération de renommage atomique, y compris l'écrasement du fichier de destination s'il existe et si les autorisations le permettent.

Existe-t-il un moyen d'obtenir la même sémantique sous Windows? Je connais MoveFileTransaced () sur Vista et Server 2008, mais j'en ai besoin pour supporter Win2k et plus.

Le mot clé ici est atomique ... la solution ne doit pas pouvoir échouer d'une manière qui laisse l'opération dans un état incohérent.

J'ai vu beaucoup de gens dire que c'était impossible sur win32, mais je vous le demande, est-ce vraiment?

Veuillez fournir des citations fiables si possible.

63
teratorn

Win32 ne garantit pas les opérations de métadonnées sur les fichiers atomiques. Je fournirais une citation, mais il n'y en a pas - le fait qu'il n'y ait pas de garantie écrite ou documentée signifie autant.

Vous allez devoir écrire vos propres routines pour soutenir cela. C'est malheureux, mais vous ne pouvez pas vous attendre à ce que win32 fournisse ce niveau de service - il n'a tout simplement pas été conçu pour cela.

16
Adam Davis
33
edg

Dans Windows Vista et Windows Server 2008, une fonction de déplacement atomique a été ajoutée - MoveFileTransaced ()

Malheureusement, cela n'aide pas avec les anciennes versions de Windows.

article intéressant ici sur MSDN .

15
Andrew

vous avez toujours l'appel rename () sur Windows, bien que j'imagine que les garanties que vous voulez ne peuvent pas être faites sans connaître le système de fichiers que vous utilisez - aucune garantie si vous utilisez FAT par exemple.

Toutefois, vous pouvez utiliser MoveFileEx et utiliser les options MOVEFILE_REPLACE_EXISTING et MOVEFILE_WRITE_THROUGH. Ce dernier a cette description dans MSDN:

La définition de cette valeur garantit qu'un déplacement effectué en tant qu'opération de copie et de suppression est vidé sur le disque avant le retour de la fonction. Le vidage se produit à la fin de l'opération de copie.

Je sais que ce n'est pas nécessairement la même chose qu'une opération de changement de nom, mais je pense que c'est peut-être la meilleure garantie que vous obtiendrez - s'il le fait pour un déplacement de fichier, il devrait le faire pour un changement de nom plus simple.

9
gbjbaanb

À partir de Windows 10 1607, NTFS prend en charge une opération de changement de nom de remplacement atomique. Pour ce faire, appelez NtSetInformationFile (..., FileRenameInformationEx, ...) et spécifiez l'indicateur FILE_RENAME_POSIX_SEMANTICS. Ou de manière équivalente dans Win32, appelez SetFileInformationByHandle (..., FileRenameInfoEx, ...) et spécifiez l'indicateur FILE_RENAME_FLAG_POSIX_SEMANTICS.

4
Craig Barkhouse

Un bon nombre de réponses mais pas celle que j'attendais ... J'avais compris (peut-être à tort) que MoveFile pouvait être atomique à condition que le les étoiles étaient alignées, des drapeaux étaient utilisés et le système de fichiers était le même sur la source que la cible. Sinon, l'opération reviendrait à un fichier [Copier-> Supprimer].

Étant donné que; J'avais également compris que MoveFile - quand il est atomique - ne faisait que définir les informations de fichier qui pourraient également être faites ici: setfileinfobyhandle .

Quelqu'un a donné une conférence intitulée " Racing the Filesystem " qui va plus en profondeur à ce sujet. (environ 2/3 vers le bas, ils parlent de renommer atomique)

2
sehafoc

La documentation MSDN évite d'indiquer clairement quelles API sont atomiques et lesquelles ne le sont pas, mais Niall Douglas déclare dans son Cppcon 2015 talk que la seule fonction atomique est

SetFileInformationByHandle

avec FILE_RENAME_INFO.ReplaceIfExists défini sur true. Il est disponible à partir de Windows Vista/2008 Server.

Niall est l'auteur d'un très compliqué bibliothèque LLFIO et est un expert des conditions de course du système de fichiers, donc je crois que si vous écrivez un algorithme où l'atomicité est cruciale, mieux vaut prévenir que guérir et utiliser le suggéré fonction même si rien dans la description de ReplaceFile indique que ce n'est pas atomique.

1
Violet Giraffe