Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Tail a file in Groovy

Tags:

groovy

I am wondering is there is a simple way to tail a file in Groovy? I know how to read a file, but how do I read a file and then wait for more lines to be added, read them, wait, etc...

I have what I am sure is a really stupid solution:

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

Note that I am not really interested in invoking the Unix "tail" command. Unless it is the only solution.

like image 511
Phil Avatar asked Oct 26 '11 16:10

Phil


1 Answers

I wrote a groovy class which resembles the basic tail functionality:

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 method taks a file and closure as parameters. It will run in a separate thread and will pass each new line that will be appended to the file to the given closure. The tail method will run until the stop method is called on the TailReader instance. Here's a short example of how to use the TailReader class:

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()
like image 93
Christoph Metzendorf Avatar answered Sep 16 '22 14:09

Christoph Metzendorf