Sunday, 23 February 2014

JTail - Java Tail command with NIO 2

The old way


As far as I can tell every implementation of the UNIX tail command in java uses a variation of the following2 3:
open file
while (true)
{
    try
    {
        read file
        write file to output
        thread.sleep(1 second)
    } catch (InterruptedException) {}
}
close file

Now if you look at the source code of tail5 in UNIX, it checks for the existence of inotify1. Java 7 has something similar (but with less features) called the WatchService as part of the NIO.2.

The new way with NIO 2

The part containing the code interfacing with the WatchService of NIO.2 can be found in the FileSystemWatcher java class.

You can find the source code to FileSystemWatcher.java on my github account.

Here's the UML schema for the FileSystemWatcher class. (slightly simplified)

Examples

$ java -classpath jtail.jar;jopt-simple-4.5.jar com.tools.jtail.Jtail --help

$ java -classpath jtail.jar;jopt-simple-4.5.jar com.tools.jtail.Jtail -version

$ java -classpath jtail.jar;jopt-simple-4.5.jar com.tools.jtail.Jtail ipsum.txt

Notes

  • The WatchService, unlike inotify, can only watch directories. Otherwise you receive a java.nio.file.NotDirectoryException.
  • One of the things I like, is the fact that the watchservice, if the filesystem does not support filemonitoring, gracefully falls back to the polling.4
  • I could have used a Path.newByteChannel method of NIO.26, instead of relying on the old RandomAccessFile class. I'll rewrite it someday.
  • I have not done extensive testing, if you find a file and command line that does not work, please do notify me.
  • Where Linux seems to provide filesystem events regularly, Windows seems to be lazy in that regard. I've tried it with a JBoss logfile in Windows, but I only got sporadic events at best. Investigation ongoing.

References

[1] Wikipedia - inotify
http://en.wikipedia.org/wiki/Inotify
[2] Java tail implementation
https://gist.github.com/amelandri/1376896
[3] Java tail
http://melandri.net/2009/05/29/java-tail/
[4] WatchService (Java Platform SE 7)
http://docs.oracle.com/javase/7/docs/api/java/nio/file/WatchService.html
[5] GNU core utilities
http://www.gnu.org/software/coreutils/
[6] StackOverflow - Java reading strings from a random access file with buffered input
http://stackoverflow.com/questions/4305094/java-reading-strings-from-a-random-access-file-with-buffered-input
Manpage : tail
http://unixhelp.ed.ac.uk/CGI/man-cgi?tail
Oracle Tutorial - Reading and Writing Files by Using Channel I/O
http://docs.oracle.com/javase/tutorial/essential/io/file.html#channelio
Oracle Tutorial - Random access files
http://docs.oracle.com/javase/tutorial/essential/io/rafs.html
Oracle Tutorial - Watching a Directory for Changes
http://docs.oracle.com/javase/tutorial/essential/io/notification.html
JOpt Simple - a Java command line parsing library
http://pholser.github.io/jopt-simple/index.html

1 comment:

  1. How to Choose a Graphics Tablet that Fits Your Needs

    The first time I tried a Wacom tablet is only comparable with the day I discovered Photoshop, bought my first laptop, tested an Apple computer or I met my girlfriend for the first time - geek joke, honey. But, why are Wacom tablets so special? In this post we'll review the advantages of these tablets.

    Choosing the Correct Drawing Tips

    In my opinion, it must be a Wacom tablet.

    The most relevant technical specification is pressure sensitivity. The more, the better.

    Smaller tablets are better, cheaper, easier to fit into your desktop, and they work just like the bigger ones. I would only choose the big model if you're going to use it for CAD.

    Think about the use you'll give to your tablet. If you want if for painting, coloring and photo manipulation, it will be 100% useful. For drawing, only Cintiq models are really good, and for designing, you need no more than a mouse.

    There are second hand markets or brand new old models. They are really worth checking.

    ReplyDelete