1

I'm trying to use Java to implement the Unix tail utility to read a log file as new lines are added. The log file has new lines written every 15 minutes. Once the BufferedReader reaches the end of the file, I have it sleep for a few minutes and when it wakes up it checks if new lines exist in the file. My code looks something like this:

String line;
BufferedReader br = new BufferedReader(new FileReader("logfile.log"));
while (alive) {
    line = br.readline();
    if (line != null) {
        processLine(line);
    } else {
        Thread.sleep(1000 * 60 * 5);
    }
}

For some reason after the BufferedReader reads the last line for the first time, it will not be able to detect any new lines that come in after that point. Does anyone have any ideas? Thanks!

* Update * The really weird thing is that this code works fine if I only read the log for the current day. However if I read the previous day, close it, and then open the current day, the problem exists. Using data from previous days log is a requirement of the program.

Test code looks like this:

        String yestFile = "\\\\2012\\06\\28\\logfile.log"; 
        String todayFile = "\\\\2012\\06\\29\\logfile.log"; 

        FileWriter out;
        String outputFile = "c:\\temp\\brOut.txt";
        File outFile = new File(outputFile);
        if (!outFile.exists()) {
            outFile.createNewFile();
        }
        out = new FileWriter(outputFile);

        String line;
        String file = yestFile;
        while (true) {
            BufferedReader br = new BufferedReader(new FileReader(file));
            while (true) {
                line = br.readLine();
                if (line != null) {
                    out.write(line + "\n");
                } else {
                    if (file.equals(yestFile)) {
                        br.close();
                        br = null;
                        file = todayFile;
                        break;
                    }
                    Thread.sleep(1000 * 60);
                }
            }
        }

* Update 2 * Thanks for all suggestions, but I decided the most effective solution is just to prevent from hitting the end of the file until the end of the day. Each line of the log indicates a time for when that event happened so I just use that to lag 20 minutes behind the current system time.

long diff = System.currentTimeMillis() - eventCal.getTimeInMillis();
if (diff < _20_MINUTES) {
    Thread.sleep(_20_MINUTES - diff);
}
JCB
  • 1,797
  • 5
  • 18
  • 22

1 Answers1

0

Once the buffered reader encounters the EOF character when it reaches the end of the file for the first time, br.readline() will never return anything except null.

String line;
BufferedReader br = new BufferedReader(new FileReader("logfile.log"));
 while (alive) {
     line = br.readLine();
     if (line != null) {
         processLine(line);
     } else {
         Thread.sleep(1000 * 60 * 5);
         br.read();
     }
 }

And surround the whole thing in a try/catch, of course

namenamename
  • 195
  • 7
  • Thank you for the suggestion. My concern is that there is a new log created for every day, and by the end of the day there are about 30,000 lines so I wonder if there is a more efficient way. Is there is a better way than readline() to advance a BufferedReader. – JCB Jun 29 '12 at 14:28
  • This statement is untrue. BufferedReader does not retain an EOF state, see the source code, and the fact that his code works in one situation proves it. Your revised solution loses characters. Downvote. – user207421 Jul 01 '12 at 01:43
  • I tested this and it does indeed work without losing any characters. Did you actually try the code? – namenamename Jul 02 '12 at 13:21