Java RandomAccessFile.java under linux not working correctly -
im trying implement simple tail -f linux command in java. here code.
try { // position within file file file = new file("/home/curuk/monitored/log.txt"); randomaccessfile rafile = new randomaccessfile(file, "r"); long last = file.lastmodified(); // last time file checked changes long position = file.length(); while (true) { if (file.lastmodified() > last) { last = file.lastmodified(); readfromfile(rafile, (int) position, (int) (file.length() - position)); position = file.length(); } thread.sleep(1000); } } catch (ioexception e) { e.printstacktrace(); } private byte[] readfromfile(randomaccessfile file, int position, int size) throws ioexception { file.seek(position); byte[] bytes = new byte[size]; system.err.println(file.read(bytes, 0, size)); string s = new string(bytes); system.err.println(s); return bytes; } the problem under linux os, file.read(bytes, 0, size) returns -1, while under windows same snippet of code works fine (always prints new line).
edit:
i solved problem adding rafile = new randomaccessfile(file, "r"); @ every iteration.
while (true) { rafile = new randomaccessfile(file, "r"); if (file.lastmodified() > last) { last = file.lastmodified(); readfromfile(rafile, (int) position, (int) (file.length() - position)); position = file.length(); } thread.sleep(1000); } don't know why, works fine under linux well. effort guys
here solution entirely based on java 7, using new watchservice infrastructure:
works, quite crude...
public final class baz { public static void main(final string... args) throws ioexception { // paths containing directory , file want spy final path dir = paths.get("/tmp"); final path file = dir.resolve("foo.txt"); // watch service our default filesystem // interested in modifications , deletions final watchservice service = filesystems.getdefault().newwatchservice(); dir.register(service, standardwatcheventkinds.entry_modify, standardwatcheventkinds.entry_delete); // charset decoder -- reading bytes file, // need decode them string final charsetdecoder decoder = standardcharsets.utf_8.newdecoder() .onmalformedinput(codingerroraction.ignore) .onunmappablecharacter(codingerroraction.ignore); try ( // open seekablebytechannel file -- read final seekablebytechannel channel = files.newbytechannel(file, standardopenoption.read); ) { long oldsize; while (true) { // current size of our file oldsize = channel.size(); try { // grab key final watchkey key = service.poll(1l, timeunit.seconds); if (key == null) // no events... continue; (final watchevent<?> e: key.pollevents()) { @suppresswarnings("unchecked") final watchevent<path> event = (watchevent<path>) e; // kind of event, whom applies final watchevent.kind<path> kind = event.kind(); final path context = dir.resolve(event.context()); // if not us, don't care if (!context.equals(file)) continue; // if our file has disappeared, exit if (kind == standardwatcheventkinds.entry_delete) { system.err.println("file deleted"); system.exit(0); } // ok, it's modification, , our file: read tail doread(oldsize, decoder, channel); } // reset key next batch of events key.reset(); } catch (interruptedexception e) { // service.poll() interrupted: out break; } } } } private static void doread(final long oldsize, final charsetdecoder decoder, final seekablebytechannel channel) throws ioexception { final long newsize = channel.size(); if (newsize <= oldsize) return; final int bufsize = (int) (newsize - oldsize); final bytebuffer buf = bytebuffer.allocate(bufsize); channel.position(oldsize).read(buf); buf.rewind(); decoder.reset(); system.out.println(decoder.decode(buf).tostring()); } }
Comments
Post a Comment