2011-10-26 11 views
9

Me pregunto si hay una manera simple de cola un archivo en Groovy? Sé cómo leer un archivo, pero ¿cómo leo un archivo y luego espero a que se agreguen más líneas, leerlas, esperar, etc. ...Cola de un archivo en Groovy

Tengo lo que estoy seguro es una solución realmente estúpida:

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

Tenga en cuenta que no estoy realmente interesado en invocar el comando "tail" de Unix. A menos que sea la única solución.

+2

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

Respuesta

12

escribí una clase maravilloso que se asemeja a la funcionalidad básica de la cola:

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() 
    } 
} 

Los tail TAKS método un archivo y cierre como parámetros. Se ejecutará en un hilo separado y pasará cada nueva línea que se adjuntará al archivo para el cierre dado. El método tail se ejecutará hasta que se llame al método stop en la instancia TailReader. He aquí un breve ejemplo de cómo utilizar la clase 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

que doesn' solo amo a Groovy? – scottb

2

En respuesta a Christoph:
Por mi caso de uso, he sustituido el bloque

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 => para garantizar que las líneas vacías se generan también
while (... => para asegurar que cada línea se lee tan rápido como sea posible

Cuestiones relacionadas