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.