2011-10-26 27 views
9

Tôi tự hỏi có một cách đơn giản để đuôi một tệp trong Groovy không? Tôi biết cách đọc một tệp, nhưng làm cách nào để đọc một tệp và sau đó đợi thêm các dòng để thêm, đọc chúng, chờ, vv ...Đuôi một tệp trong Groovy

Tôi có những gì tôi chắc chắn là một giải pháp thực sự ngu ngốc:

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

Lưu ý rằng tôi không thực sự quan tâm đến việc gọi lệnh "đuôi" của Unix. Trừ khi nó là giải pháp duy nhất.

+2

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

Trả lời

12

Tôi đã viết một lớp groovy đó tương tự như chức năng đuôi cơ bản:

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

Các tail phương pháp taks một tập tin và đóng cửa như là tham số. Nó sẽ chạy trong một chủ đề riêng biệt và sẽ vượt qua mỗi dòng mới sẽ được nối vào tập tin để đóng cửa nhất định. Phương thức tail sẽ chạy cho đến khi phương thức stop được gọi trên cá thể TailReader. Dưới đây là một ví dụ ngắn về cách sử dụng các lớp 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

người doesn' t chỉ yêu Groovy? – scottb

2

Trong thư trả lời để Christoph:
Đối với trường hợp sử dụng của tôi, tôi đã thay thế khối

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

với

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

... != null => để đảm bảo các dòng trống cũng được xuất ra
while (... => để đảm bảo mỗi dòng được đọc càng nhanh càng tốt

Các vấn đề liên quan