3

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();
    }
}
7
  • Try using the newer NIO classes, as they might provide more direct access to the file. The older IO classes are probably using a Linux API that opens the file read-only, which might be accessing a snapshot of the file. (I guessing here). Commented Aug 17, 2015 at 18:20
  • 1
    I had to add a throws Exception to main to take care of the missing try-catch around reader.close, I also changed your path to /tmp/abc.log. Then I did a touch /tmp/abc.log and run the program. Finally, I did an echo test >>/tmp/abc.log, and I did see the program producing the output. Can you provide instructions to reproduce the issue? Commented Aug 17, 2015 at 18:22
  • I also see the expected output both when echoing and when using nano to write to the file through the shell. However I don't see the output when I append a line to the log using gedit. Very strange. I think it is safe to assume that the game console that is writing to the log file likely suffers from the same problem that gedit is experiencing, whatever that may be! Commented Aug 17, 2015 at 19:31
  • If you do a "cat" of the file, do you see the new line, while not seeing it from your program? Commented Aug 17, 2015 at 19:52
  • That is correct Roberto. Commented Aug 18, 2015 at 3:19

1 Answer 1

0

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

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.