¿Qué sucede cuando lees un archivo mientras se sobrescribe?

Respuestas:

19

Eso depende de lo que haga el escritor.

Si el escritor sobrescribe el archivo existente, entonces el lector verá el nuevo contenido cuando el escritor supere al lector, si alguna vez. Si el escritor y el lector proceden a velocidades variables, el lector puede ver alternativamente contenido antiguo y nuevo.

Si el escritor trunca el archivo antes de que comience a escribir, el lector se ejecutará contra el final del archivo en ese punto.

Si el escritor crea un nuevo archivo y luego mueve el nuevo archivo al nombre anterior, el lector seguirá leyendo el archivo anterior. Si se mueve o elimina un archivo abierto, los procesos que tienen el archivo abierto siguen leyendo desde ese mismo archivo. Si se elimina el archivo, en realidad permanece en el disco (pero sin forma de abrirlo nuevamente) hasta que el último proceso lo haya cerrado.

Los sistemas Unix tienden a no tener bloqueos obligatorios . Si una aplicación quiere asegurarse de que su componente de escritor y su componente de lector no pisen los dedos del otro, depende del desarrollador usar el bloqueo adecuado. Hay algunas excepciones en las que un archivo que está abierto por el núcleo puede estar protegido de la escritura por las aplicaciones del usuario, por ejemplo, una imagen del sistema de archivos montado en un bucle o un ejecutable que se ejecuta en algunas variantes de Unix.

Gilles 'SO- deja de ser malvado'
fuente
Gilles, ¿tu explicación también se aplica en ftp/ sftpescenarios? Digamos que un proceso comienza a leer un ftparchivo transmitido mientras otra versión del mismo archivo lo sobrescribe debido a una nueva transmisión.
iruvar
@ 1_CR Sí. En ese caso, el escritor y el lector son los procesos ftpd.
Gilles 'SO- deja de ser malvado'
¿Cuál es el significado de adelantar aquí?
Victor Choy
@VictorChoy Significado estándar: comenzar detrás / después de otra persona y, en algún momento, adelantarse.
Gilles 'SO- deja de ser malvado'
18

Es una condición de carrera clásica, por lo que el resultado es impredecible por definición.

Entre otros, depende de

  • fopen(3)o open(2)modos de escritura,
  • cómo / si el escritor está almacenando en búfer su salida,
  • cómo el lector está leyendo el archivo,
  • la diferencia de velocidad entre el lector y el escritor
  • La diferencia horaria entre la lectura y el comienzo del escritor.
  • Y, por supuesto, en las máquinas modernas de varios núcleos, las cosas se complican aún más por otros factores inferiores (por ejemplo, la programación de procesos).

Si necesita poder leer un archivo mientras se está reescribiendo, puede hacer que el escritor haga una copia transitoria del archivo, modificarlo y luego volver a copiarlo en el archivo original. Así lo rsynchace, por ejemplo. Hay varias maneras de implementar esto, pero no hay almuerzo gratis. Cada método tiene sus propias deficiencias y repercusiones.

Alexios
fuente
1
Esta respuesta es mucho más completa que la mía. Borrando mi respuesta.
Killermist
0

Los respondedores anteriores tienen explicaciones más completas que esta, pero aquí hay un truco que definitivamente también funciona, prácticamente haciendo exactamente lo que quiere:

$ tail -f <filename>

Le mostrará el final del archivo mientras se está escribiendo. Práctico si desea canalizar STDERR a un archivo pero aún lo ve en otra ventana de terminal, por ejemplo.

Willoughby Will
fuente