Tant que vous ne déplacez pas le fichier au-delà des frontières du système de fichiers, l'opération doit être sûre. Cela est dû au mécanisme, à la façon dont »le déplacement« se fait réellement.
Si vous mv
un fichier sur le même système de fichiers, le fichier n'est pas réellement touché, mais seule l'entrée du système de fichiers est modifiée.
$ mv foo bar
fait quelque chose comme
$ ln foo bar
$ rm foo
Cela créerait un lien dur (une deuxième entrée de répertoire) pour le fichier (en fait l'inode pointé par l'entrée du système de fichiers) foo
nommé bar
et supprimer l' foo
entrée. Depuis lors de la suppression foo
, il existe une deuxième entrée du système de fichiers pointant vers foo
l'inode, la suppression de l'ancienne entrée foo
ne supprime en fait aucun bloc appartenant à l'inode.
Votre programme se joindrait volontiers au fichier de toute façon, car son descripteur de fichier ouvert pointe vers l'inode du fichier, pas l'entrée du système de fichiers.
Remarque: Si votre programme ferme et rouvre le fichier entre les écritures, vous finirez par avoir un nouveau fichier créé avec l'ancienne entrée du système de fichiers!
Déplacements entre systèmes de fichiers:
Si vous déplacez le fichier au-delà des frontières du système de fichiers, les choses deviennent laides. Dans ce cas , vous ne pouviez pas garantir d'avoir votre dossier en gardant constante, depuis mv
REELLEMENT
- créer un nouveau fichier sur le système de fichiers cible
- copier le contenu de l'ancien fichier dans le nouveau fichier
- supprimer l'ancien fichier
ou
$ cp /path/to/foo /path/to/bar
$ rm /path/to/foo
resp.
$ touch /path/to/bar
$ cat < /path/to/foo > /path/to/bar
$ rm /path/to/foo
Selon que la copie atteint la fin du fichier lors de l'écriture de votre application, il peut arriver que vous ayez seulement la moitié d'une ligne dans le nouveau fichier.
De plus, si votre application ne ferme pas et ne rouvre pas l'ancien fichier, elle continuera à écrire dans l'ancien fichier, même s'il semble être supprimé: le noyau sait quels fichiers sont ouverts et bien qu'il supprime l'entrée du système de fichiers, il ne supprimera pas l'inode de l'ancien fichier et les blocs associés jusqu'à ce que votre application ferme son descripteur de fichier ouvert.
rename()
appel système. Ainsi, la version originale demv
effectivement appelélink()
pour créer le lien dur, suivieunlink()
de supprimer le nom d'origine.rename()
a été ajouté dans FreeBSD, pour l'implémenter atomiquement dans le noyau.file-system borders
?Puisque vous dites que vous utilisez node.js, je suppose que vous utiliseriez
fs.rename()
(oufs.renameSync()
) pour renommer les fichiers. Cette méthode node.js est documentée pour utiliser l' appel système rename (2) , qui ne touche en aucune façon le fichier lui-même, mais modifie simplement le nom sous lequel il est répertorié dans le système de fichiers:En particulier, notez la dernière phrase citée ci-dessus, qui dit que tous les descripteurs de fichiers ouverts (tels que votre programme utiliseraient pour écrire dans le fichier) continueront à pointer vers lui même après qu'il a été renommé. Ainsi, il n'y aura aucune perte ou corruption de données même si le fichier est renommé pendant qu'il est simultanément écrit.
Comme le note Andreas Weise dans sa réponse , l'appel système rename (2) (et donc
fs.rename()
dans node.js) ne fonctionnera pas au-delà des limites du système de fichiers. Ainsi, tenter de déplacer un fichier vers un autre système de fichiers de cette manière échouera tout simplement.La
mv
commande Unix essaie de masquer cette limitation en détectant l'erreur et, à la place, en déplaçant le fichier en copiant son contenu dans un nouveau fichier et en supprimant l'original. Malheureusement, le déplacement de fichiers comme celui- ci risque de perdre des données si le fichier est déplacé pendant son écriture. Ainsi, si vous souhaitez renommer en toute sécurité des fichiers qui peuvent être écrits simultanément, vous ne devez pas utilisermv
(ou, au moins, vous devez vous assurer que le nouveau et l'ancien chemin se trouvent sur le même système de fichiers).la source