Tengo una aplicación que escribe información en un archivo. Esta información se utiliza después de la ejecución para determinar si la aplicación se aprueba / falla / es correcta. Me gustaría poder leer el archivo a medida que se escribe para poder hacer estas comprobaciones de aprobación / falla / corrección en tiempo real.
Supongo que es posible hacer esto, pero ¿cuáles son los problemas involucrados al usar Java? Si la lectura se pone al día con la escritura, ¿esperará más escrituras hasta que se cierre el archivo, o la lectura arrojará una excepción en este punto? Si es lo último, ¿qué hago entonces?
Mi intuición me está empujando actualmente hacia BufferedStreams. ¿Es este el camino a seguir?
Respuestas:
No se pudo hacer que el ejemplo funcionara
FileChannel.read(ByteBuffer)
porque no es una lectura de bloqueo. Sin embargo, el código siguiente funciona:Por supuesto, lo mismo funcionaría como un temporizador en lugar de un hilo, pero eso se lo dejo al programador. Todavía estoy buscando una mejor manera, pero esto funciona para mí por ahora.
Ah, y advertiré esto: estoy usando 1.4.2. Sí, sé que todavía estoy en la edad de piedra.
fuente
Si desea leer un archivo mientras se escribe y solo leer el contenido nuevo, lo siguiente le ayudará a lograr lo mismo.
Para ejecutar este programa, lo ejecutará desde el símbolo del sistema / ventana de terminal y pasará el nombre del archivo a leer. Leerá el archivo a menos que elimine el programa.
Java FileReader c: \ myfile.txt
A medida que escribe una línea de texto, guárdela desde el bloc de notas y verá el texto impreso en la consola.
fuente
BufferedReader
creación en cada llamada de bucle no tiene sentido. Al crearse una vez, no sería necesario omitir, ya que el lector en búfer leería las nuevas líneas a medida que lleguen.También puede echar un vistazo al canal java para bloquear una parte de un archivo.
http://java.sun.com/javase/6/docs/api/java/nio/channels/FileChannel.html
Esta función del
FileChannel
podría ser un comienzoUna invocación de este método se bloqueará hasta que se pueda bloquear la región
fuente
Estoy totalmente de acuerdo con la respuesta de Joshua , Tailer es apto para el trabajo en esta situación. Aquí hay un ejemplo :
Escribe una línea cada 150 ms en un archivo, mientras lee este mismo archivo cada 2500 ms
fuente
La respuesta parece ser "no" ... y "sí". Parece que no hay una forma real de saber si un archivo está abierto para escritura por otra aplicación. Por lo tanto, la lectura de un archivo de este tipo progresará hasta que se agote el contenido. Seguí el consejo de Mike y escribí un código de prueba:
Writer.java escribe una cadena en el archivo y luego espera a que el usuario presione enter antes de escribir otra línea en el archivo. La idea es que se pueda iniciar, luego se puede iniciar un lector para ver cómo maneja el archivo "parcial". El lector que escribí está en Reader.java.
Writer.java
Reader.java
No hay garantías de que este código sea la mejor práctica.
Esto deja la opción sugerida por Mike de verificar periódicamente si hay nuevos datos para leer del archivo. Esto requiere la intervención del usuario para cerrar el lector de archivos cuando se determina que la lectura está completa. O bien, el lector debe conocer el contenido del archivo y poder determinar la condición de fin de escritura. Si el contenido fuera XML, el final del documento podría usarse para señalar esto.
fuente
No es Java per-se, pero puede tener problemas en los que haya escrito algo en un archivo, pero aún no se ha escrito en realidad; puede estar en un caché en algún lugar, y leer desde el mismo archivo puede que en realidad no le dé la nueva información.
Versión corta: use flush () o cualquier llamada al sistema relevante para asegurarse de que sus datos estén realmente escritos en el archivo.
Tenga en cuenta que no estoy hablando de la memoria caché del disco a nivel del sistema operativo; si sus datos entran aquí, deberían aparecer en un read () después de este punto. Puede ser que el propio lenguaje almacene en caché las escrituras, esperando hasta que se llene un búfer o se vacíe / cierre el archivo.
fuente
Hay una cola gráfica Java de código abierto que hace esto.
https://stackoverflow.com/a/559146/1255493
fuente
No puede leer un archivo que se abre desde otro proceso utilizando FileInputStream, FileReader o RandomAccessFile.
Pero usar FileChannel directamente funcionará:
fuente
Nunca lo he probado, pero debería escribir un caso de prueba para ver si la lectura de una transmisión después de haber llegado al final funcionará, independientemente de si hay más datos escritos en el archivo.
¿Hay alguna razón por la que no pueda utilizar un flujo de entrada / salida canalizado? ¿Se están escribiendo y leyendo los datos desde la misma aplicación (si es así, tiene los datos, por qué necesita leer desde el archivo)?
De lo contrario, puede leer hasta el final del archivo, luego monitorear los cambios y buscar donde lo dejó y continuar ... aunque tenga cuidado con las condiciones de la carrera.
fuente