Reputation: 31
I put 'ON LINUX' in caps not to annoy you but because I have already been able to do this on Windows using 3 different file reading Classes. FileIntputStream BufferedReader RandomAccessFile (The last two I am sure of but the first could be wrong - my memory is baaad.) All of these are working perfectly on windows for me. My intended use of these readers is to read a text file line by line in real time, meaning, when a new version of this file is saved with a new line appended to it, the java program reads this line, does something with it and then continues checking for another new line.
I tried compiling using Java 7 openJDK, Java 7 Oracle, and Java 8 Oracle environments and all the resulting .jars worked fine on windows, and since Java is cross-platform I assumed they would work on Linux too (right?), yet every version I compile has failed when tested on linux. This was brought to my attention by a community forum member running linux Red Hat, no errors/exceptions, looked like it was running but just didn't work. I installed Ubuntu today and tried it for myself: The readers will read the original file fine but do not "stream" the file in real time. Changes to the file go unnoticed. I am very confused as to how this is possible and honestly I'm surprised it hasn't been brought up anywhere (as far as I can tell lol). Hopefully this means that I've made a stupid mistake somewhere in regards to ensuring linux compatibility that someone might track down. Any and all help/answers/workarounds are appreciated!
Here is an example of the code I am trying to implement into my program:
import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.RandomAccessFile;
public class Driver {
public static void main(String[] args) {
RandomAccessFile reader = null;
try {
reader = new RandomAccessFile(new File("/home/citats/csgo/console.log"), "r");
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
String currLine;
Boolean done = false;
while (!done) {
try {
if ((currLine = reader.readLine()) != null)
{
System.out.println(currLine);
if (currLine.equals("done"))
done = true;
} else
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
reader.close();
}
}
Upvotes: 3
Views: 3679
Reputation: 2884
Tailing a file
To get functionality like tail -f
where your solution is watching for new file updates then doing something with them see this answer: How can I follow a file like "Tail -f" does in Java without holding the file open (Prevent rename/delete). The source of this is informative for what you are attempting. I'm suspecting some of the seeks get around the issue you are seeing. Tailer Source
An alternative and quite interesting way to achieve similar results but with more power is with JavaRX-file where you can arrange for the new changes to be delivered in a more asychronous manner with Java NIO. There's an example on their main page: RxJava file github page
import com.github.davidmoten.rx.FileObservable;
import rx.Observable;
import java.io.File;
Observable<String> items =
FileObservable.tailer()
.file("/var/log/server.log")
.startPosition(0)
.sampleTimeMs(500)
.chunkSize(8192)
.utf8()
.tailText();
RxJava
For more information about why use JavaRx see the RxJava project
Upvotes: 0