2010-03-29 17 views
9

Devo essere in grado di simulare 'tail -f' con Java. Sto provando a leggere un file di registro mentre viene scritto da un altro processo, ma quando apro il file per leggerlo, blocca il file e l'altro processo non può più scrivere su di esso. Qualsiasi aiuto sarebbe molto apprezzato!Java: apertura e lettura da un file senza bloccarlo

Ecco il codice che sto usando attualmente:

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

Se non funziona nient'altro, è possibile utilizzare jni per ottenere l'API di win32 (presumendo che tu sia su Windows, altrimenti qualsiasi API con cui stai lavorando). – Blindy

+1

utilizzando la win32 api sarebbe la cosa più brutta;) – Bozho

+0

Heh dato che non conosco bene Java, questo è il miglior consiglio che ho :) – Blindy

risposta

0

Guardate l'API FileChannel here. Per bloccare il file è possibile controllare here

+0

È possibile esaminare la possibile domanda duplicata in StackOverflow all'indirizzo http://stackoverflow.com/questions/128038/how-can-i-lock-a-file- using-java-if-possible – Cshah

+0

Hmm. L'ho cercato e ho provato diverse strategie - anche usando java.io.RandomAccessFile oltre a FileChannel, ma non riesco ancora a lasciare che un altro processo scriva su un file che sto leggendo in Java. – rogue780

+0

rogue780 - pubblica le strategie che hai provato. Si noti che se l'altro processo richiede un blocco esclusivo prima che scriva sul file, allora si è abbastanza brindisi (ovviamente, tail non funzionerebbe neanche in questa situazione). Ma hai provato a bloccare (con un blocco di lettura non esclusivo) la parte superiore del file? –

0

Windows utilizza il blocco obbligatorio per i file se non si specificano i flag di condivisione corretti mentre si apre. Se si desidera aprire un file occupato, è necessario Win32-API CreateFile un handle con i flag di condivisione FILE_SHARE_DELETE | FILE_SHARE_READ | FILE_SHARE_WRITE.

Questo è utilizzato all'interno del JDK in pochi punti per aprire file per la lettura di attributi e cose, ma per quanto posso vedere non è esportato/disponibile al livello della libreria di classi Java. Quindi dovresti trovare una libreria nativa per farlo.

penso come un rapido lavoro intorno a te può leggere process.getInputStream() dal comando "cmd /D/C type file.lck"

+1

Non sono sicuro quando è cambiato, ma il mio file aperto usando RandomAccessFile si apre con SHARE_READ e SHARE_WRITE. Ho provato con ProcMon.exe – kervin

0

Se si desidera una soluzione rapida, che potrebbe non essere il più elegante, è sufficiente monitorare il file per le modifiche di dimensione, quindi aprire il file , cercare l'ultima posizione, leggere i nuovi dati, chiudere il file e continuare a monitorare.

E se le prestazioni non sono un problema, questo dovrebbe funzionare bene. Se, tuttavia, è necessario prestazioni, è preferibile utilizzare una soluzione più sofisticata basata su API di file IO avanzate.

+0

Non se non riesce ad aprirlo a causa del blocco. – EJP

5

La ricostruzione della coda è complicata a causa di alcuni casi speciali come il troncamento dei file e la cancellazione (intermedia). Per aprire il file senza bloccare l'uso StandardOpenOption.READ con la nuova API file di Java in questo modo:

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. 
    } 
} 

Per il mio tentativo di creare una coda in Java vedere:

Sentiti libero di prendere ispirazione da quel codice o semplicemente di copiare le parti richieste. Fammi sapere se trovi problemi di cui non sono a conoscenza.