uso practico parametros libro español curso consultas con avanzado aplicaciones java unix file-locking

java - practico - ¿Es una operación de movimiento en Unix atómico?



libro de java pdf 2018 (3)

  1. mover (renombrar) es atómico si se realiza en el mismo dispositivo. (dispositivo = mismo disco / partición)
  2. Si Foo.txt salidas de Foo.txt mueven Foo.tmp a Foo.txt más probable es que falle. (Pero si primero Foo.txt y luego lo mueves, debería funcionar). Lo que sucede es que un archivo no se elimina físicamente hasta que se cierran todos los manejadores de archivos (no hay ningún proceso que use ese archivo). Además, después de permanecer Foo.tmp en Foo.txt , tendrá 2 archivos Foo.txt. Una que se elimina pero aún se abre en la memoria (básicamente ese archivo ya no tiene una referencia en el disco) y otra que realmente reside en el disco.
  3. Pero, después de moverte, en el segundo proceso debes reabrir el archivo.

Déjame saber si estamos en la misma página con el # 1.

Supongamos que hay 2 procesos P1 y P2, y acceden a un archivo compartido Foo.txt .

Supongamos que P2 está leyendo de Foo.txt . No quiero que P1 escriba a Foo.txt mientras P2 lo está leyendo.

Así que pensé que podía hacer que P1 escribiera en Foo.tmp y, como último paso, Foo.tmp nombre de Foo.tmp a Foo.txt . Mi lenguaje de programacion es java

Entonces, mi pregunta es, ¿aseguraría esto que P2 lea los datos correctos de Foo.txt ? ¿Se confirmaría la operación de cambio de nombre una vez que P2 complete la lectura del archivo?

EDITAR

Intenté recrear este escenario de la siguiente manera:

Mi código P1 es algo como esto:

File tempFile = new File(path1); File realFile = new File(path2); BufferedWriter writer = new BufferedWriter(new FileWriter(tempFile)); for(int i=0;i<10000;i++) writer.write("Hello World/n"); writer.flush(); writer.close(); tempFile.renameTo(realFile);

y mi código P2 es:

BufferedReader br = new BufferedReader(new FileReader(file)); String line = null; while(true) { while((line=br.readLine())!=null){ System.out.println(line); Thread.sleep(1000); } br.close(); }

Mi archivo compartido de muestra:

Test Input Test Input Test Input

Estoy empezando P1 y P2 casi simultáneamente (P2 comienza primero).

Así que, según tengo entendido, a pesar de que P1 ha escrito un nuevo Foo.txt, ya que P2 ya lo está leyendo, debería leer el contenido anterior de Foo.txt hasta que vuelva a abrir un BufferedReader en Foo.txt.

Pero lo que realmente sucede es que P2 lee la Test Input tres veces, como se espera de la entrada, pero luego lee el nuevo contenido que fue escrito por P1.

Salida de P2:

Test Input Test Input Test Input Hello World Hello World Hello World . . .

Así que no funciona como debería. ¿Estoy probando este escenario mal? Siento que hay algo que me estoy perdiendo.



Una operación de rename UNIX es atómica (vea renombrar (2)). El comando mv UNIX usa renombrar si la ruta de origen y destino están en el mismo dispositivo físico. Si la ruta de destino está en un dispositivo diferente, el cambio de nombre fallará y mv copiará el archivo (que no es atómico).

Si la ruta del archivo de destino existe, el rename lo eliminará automáticamente del sistema de archivos y lo reemplazará con el nuevo archivo. El archivo no se eliminará realmente hasta que su recuento de referencia caiga a cero, por lo que si otro proceso está leyendo el archivo, seguirá leyendo el archivo anterior. Una vez que todos los procesos hayan cerrado el archivo anterior, su recuento de referencia se reducirá a cero y se reclamará el espacio de almacenamiento de archivos.