2011-10-26 14 views
9

Zastanawiam się, czy istnieje prosty sposób na zakończenie pliku w Groovy? Wiem, jak czytać plik, ale jak odczytać plik, a następnie poczekać na dodanie kolejnych linii, przeczytać je, poczekać, itd ...Zgraj plik w Groovy

Mam to, co jestem pewien, że to naprawdę głupie rozwiązanie:

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

Zauważ, że nie jestem naprawdę zainteresowany wywoływaniem polecenia Unix "tail". Chyba że jest to jedyne rozwiązanie.

+2

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

Odpowiedz

12

pisałem groovy klasy, który przypomina podstawowe funkcje Ogon

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

The tail metody ło pliku i zamknięciem parametrów. Będzie działał w osobnym wątku i przekaże każdemu nowemu wierszowi, który zostanie dołączony do pliku, do danego zamknięcia. Metoda tail będzie działać do czasu wywołania metody stop w instancji TailReader. Oto krótki przykład jak użyć klasy 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

kto robi” Po prostu kochasz Groovy? – scottb

2

w odpowiedzi na Christoph:
Dla mojego przypadku użycia, mam wymienić blok

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

z

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

... != null => w celu zapewnienia wyprowadzenia pustych linii
while (... =>, aby upewnić się, każdy wiersz jest czytany jak najszybciej