2010-03-29 15 views
9

Necesito poder imitar 'tail -f' con Java. Intento leer un archivo de registro, ya que está siendo escrito por otro proceso, pero cuando abro el archivo para leerlo, bloquea el archivo y el otro proceso ya no puede escribir en él. ¡Cualquier ayuda sería muy apreciada!Java: abrir y leer un archivo sin bloquearlo

Aquí está el código que estoy usando actualmente:

public void read(){ 
    Scanner fp = null; 
    try{ 
     fp = new Scanner(new FileReader(this.filename)); 
     fp.useDelimiter("\n"); 
    }catch(java.io.FileNotFoundException e){ 
     System.out.println("java.io.FileNotFoundException e"); 
    } 
    while(true){ 
     if(fp.hasNext()){ 
      this.parse(fp.next()); 
     }   
    }  
} 
+0

Si nada funciona, puedes usar jni para ir a la API de Win32 (suponiendo que estés en Windows, de lo contrario con la API con la que estés trabajando). – Blindy

+1

usando la api win32 sería lo más feo;) – Bozho

+0

Heh, ya que no conozco Java tan bien, ese es el mejor consejo que tengo :) – Blindy

Respuesta

0

mirar la API FileChannel here. Para bloquear el archivo, puede marcar here

+0

Puede ver la posible pregunta duplicada en stackoverflow en http://stackoverflow.com/questions/128038/how-can-i-lock-a-file- using-java-if-possible – Cshah

+0

Hmm. Lo estuve revisando e intenté varias estrategias, incluso usando java.io.RandomAccessFile además de FileChannel, pero aún no puedo dejar que otro proceso escriba en un archivo que estoy leyendo en Java. – rogue780

+0

rogue780: publica las estrategias que has probado. Tenga en cuenta que si el otro proceso requiere un bloqueo exclusivo antes de escribir en el archivo, entonces está muy tierno (por supuesto, la cola tampoco funcionaría en esta situación). ¿Pero ha intentado bloquear (con un bloqueo de lectura no exclusivo) la parte superior del archivo? –

0

Windows usa el bloqueo obligatorio para los archivos a menos que especifique los indicadores de compartir correctos mientras los abre. Si desea abrir un archivo ocupado, necesita Win32-API CreateFile un identificador con las marcas de compartir FILE_SHARE_DELETE | FILE_SHARE_READ | FILE_SHARE_WRITE.

Se usa dentro del JDK en algunos lugares para abrir archivos para leer atributos y cosas, pero hasta donde puedo ver no se exporta/está disponible para el nivel de la Biblioteca de clases Java. Entonces necesitarías encontrar una biblioteca nativa para hacer eso.

pienso como un trabajo rápido alrededor, se puede leer process.getInputStream() del comando "cmd /D/C type file.lck"

+1

No estoy seguro de cuándo cambió, pero mi archivo abierto con RandomAccessFile se abre con SHARE_READ y SHARE_WRITE. Probé usando ProcMon.exe – kervin

0

Si desea una solución rápida, que podría no ser el más elegante, simplemente supervisar el archivo de cambios de tamaño, a continuación, abra el archivo , busque el último puesto, lea los datos nuevos, cierre el archivo y siga supervisando.

Y si el rendimiento no es una preocupación, esto debería funcionar bien. Sin embargo, si necesita rendimiento, se debe preferir una solución más sofisticada basada en una API de IO de archivos más avanzada.

+0

No si no puede abrirlo debido al bloqueo. – EJP

5

Reconstruir la cola es complicado debido a algunos casos especiales como el truncamiento de archivos y la eliminación (intermedia). Para abrir el archivo sin bloquear el uso StandardOpenOption.READ con la nueva API de archivos de Java, así:

try (InputStream is = Files.newInputStream(path, StandardOpenOption.READ)) { 
    InputStreamReader reader = new InputStreamReader(is, fileEncoding); 
    BufferedReader lineReader = new BufferedReader(reader); 
    // Process all lines. 
    String line; 
    while ((line = lineReader.readLine()) != null) { 
     // Line content content is in variable line. 
    } 
} 

Por mi intento de crear una cola en Java ver:

no dude en tomar la inspiración de ese código o simplemente copiar las partes que se requieren. Avíseme si encuentra algún problema del que no tenga conocimiento.

Cuestiones relacionadas