Que se passe-t-il lorsque vous lisez un fichier alors qu'il est écrasé?

Réponses:

19

Cela dépend de ce que fait l'auteur.

Si l'écrivain écrase le fichier existant, le lecteur verra le nouveau contenu lorsque l'écrivain dépassera le lecteur, si jamais. Si l'auteur et le lecteur avancent à des vitesses variables, le lecteur peut alternativement voir l'ancien et le nouveau contenu.

Si le rédacteur tronque le fichier avant qu'il ne commence à écrire, le lecteur s'exécutera à la fin du fichier à ce point.

Si l'auteur crée un nouveau fichier puis déplace le nouveau fichier vers l'ancien nom, le lecteur continuera à lire à partir de l'ancien fichier. Si un fichier ouvert est déplacé ou supprimé, les processus qui ont ouvert le fichier continuent de lire à partir de ce même fichier. Si le fichier est supprimé, il reste sur le disque (mais sans aucun moyen de l'ouvrir à nouveau) jusqu'à ce que le dernier processus l'ait fermé.

Les systèmes Unix n'ont généralement pas de verrous obligatoires . Si une application veut s'assurer que son composant d'écriture et son composant de lecture ne marchent pas l'un sur l'autre, c'est au développeur d'utiliser le verrouillage approprié. Il y a quelques exceptions où un fichier ouvert par le noyau peut être protégé contre l'écriture par les applications utilisateur, par exemple une image de système de fichiers montée en boucle ou un exécutable en cours d'exécution sur certaines variantes Unix.

Gilles 'SO- arrête d'être méchant'
la source
Gilles, votre explication s'applique-t-elle également dans ftp/ sftpscénarios? Supposons qu'un processus commence à lire un ftpfichier transmis tandis qu'une autre version du même fichier l'écrase en raison d'une nouvelle transmission.
iruvar
@ 1_CR Oui. Dans ce cas, l'écrivain et le lecteur sont les processus ftpd.
Gilles 'SO- arrête d'être méchant'
quel est le sens du dépassement ici?
Victor Choy
@VictorChoy Signification standard: commencer derrière / après quelqu'un d'autre et à un moment donné devancer.
Gilles 'SO- arrête d'être méchant'
18

C'est une condition de course classique, donc le résultat est imprévisible par définition.

Cela dépend entre autres

  • fopen(3)ou open(2)modes d'écriture,
  • comment / si l'écrivain met en mémoire tampon sa sortie,
  • comment le lecteur lit le fichier,
  • la différence de vitesse entre le lecteur et l'écrivain,
  • la différence de temps entre le début de la lecture et de l'écriture.
  • Et bien sûr, sur les machines multicœurs modernes, les choses sont encore plus compliquées par d'autres facteurs plus bas (par exemple, la planification des processus).

Si vous devez être en mesure de lire un fichier pendant sa réécriture, vous pouvez demander au rédacteur de faire une copie transitoire du fichier, le modifier, puis le recopier dans le fichier d'origine. C'est comme rsyncça, par exemple. Il existe un certain nombre de façons de mettre en œuvre cela, mais pas de déjeuner gratuit. Chaque méthode a ses propres défauts et répercussions.

Alexios
la source
1
Cette réponse est beaucoup plus complète que la mienne. Suppression de ma réponse.
killermist
0

Les répondants précédents ont des explications plus complètes que cela, mais voici une astuce qui fonctionne aussi bien, faisant exactement ce qu'il veut:

$ tail -f <filename>

Vous montrera la fin du fichier en cours d'écriture. Pratique si vous souhaitez diriger STDERR vers un fichier mais le voir toujours dans une autre fenêtre de terminal, par exemple.

Willoughby Will
la source