2011-10-26 18 views
9

Mi chiedo se esiste un modo semplice per inserire un file in Groovy? So leggere un file, ma come faccio a leggere un file e quindi attendere che vengano aggiunte altre righe, leggerle, attendere, ecc ...Coda un file in Groovy

Ho una soluzione davvero stupida:

def lNum = 0 
def num= 0 
def numLines = 0 
def myFile = new File("foo.txt") 
def origNumLines = myFile.eachLine { num++ } 
def precIndex = origNumLines 

while (true) { 
num = 0 
lNum = 0 
numLines = myFile.eachLine { num++ } 

if (numLines > origNumLines) { 
    myFile.eachLine({ line -> 

    if (lNum > precIndex) { 
      println line 
     } 
    lNum++ 
    }) 
} 
precIndex = numLines 

Thread.sleep(5000) 
} 

Nota che non mi interessa veramente invocare il comando "coda" di Unix. A meno che non sia l'unica soluzione.

+2

http://stackoverflow.com/questions/557844/java-io-implementation-of-unix-linux-tail-f –

risposta

12

ho scritto una classe Groovy che ricorda le funzionalità di base di coda:

class TailReader { 

    boolean stop = false 

    public void stop() { 
    stop = true 
    } 

    public void tail (File file, Closure c) { 
    def runnable = { 
    def reader 

     try { 
     reader = file.newReader() 
     reader.skip(file.length()) 

     def line 

     while (!stop) { 
      line = reader.readLine() 
      if (line) { 
      c.call(line) 
      } 
      else { 
      Thread.currentThread().sleep(1000) 
      } 
     } 

     } 
     finally { 
     reader?.close() 
     } 
    } as Runnable 

    def t = new Thread(runnable) 
    t.start() 
    } 
} 

I tail metodo taks un file e di chiusura come parametri. Verrà eseguito in un thread separato e passerà ogni nuova riga che verrà aggiunta al file alla chiusura specificata. Il metodo tail verrà eseguito finché non verrà chiamato il metodo stop nell'istanza TailReader. Ecco un breve esempio di come utilizzare la classe TailReader:

def reader = new TailReader() 
reader.tail(new File("/tmp/foo.log")) { println it } 

// Do something else, e.g. 
// Thread.currentThread().sleep(30 * 1000) 

reader.stop() 
+1

che doesn' t solo amore Groovy? – scottb

2

In risposta a Christoph:
Per il mio caso d'uso, ho sostituito il blocco

line = reader.readLine() 
if (line) { 
    c.call(line) 
} 
else { 
    Thread.currentThread().sleep(1000) 
} 

con

while ((line = reader.readLine()) != null) 
    c.call(line) 
Thread.currentThread().sleep(1000)` 

... != null => per garantire l'emissione di righe vuote anche
while (... => per garantire che ogni linea viene letta più velocemente possibile