BufferedReader readLine before the line is complete

天涯浪子 提交于 2019-12-11 17:47:51

问题


I have a process (actually a webserver) that writes to a log file as the POST coming in from clients.

Then I have a separate process that reads the log file like (tail -f) in a loop:

            BufferedReader reader = new BufferedReader(new FileReader(logFilePath));
            String line = null;

            while (true)
            {
                    if ( (line = reader.readLine()) != null )
                    {
                            if (firstLine == null) firstLine = line;
                            processLine(line);
                            continue;
                    }

                    try
                    {
                            Thread.sleep(sleepTime);
                            long ts = System.currentTimeMillis();
                    } catch (InterruptedException e) {
                            Thread.currentThread().interrupt();
                            break;
                    }
            }

This works very well 99% of the time but occasionally, the line I read in by BufferedReader.readLine isn't a complete line. I suppose that's because the writer (the webserver) hasn't finished flushing all the bytes of the line to the file yet.

Any suggestions to fix or work around this? Thanks a lot!


回答1:


Having worked with multiple processes that need to access one file at about the same time (often one process right after another), I've found (along with other developers I've worked with) that a "trailer" file is good to use to indicate when one process is done interacting with the file that needs to be accessed by another process.

I'm not sure how often your webserver is writing to this log and also how quickly your Java process needs to read it, but if there's time that can lapse between each process's access to the file, a trailer file can be written out that indicates when your webserver is done writing to the file. Your Java process can first check if the trailer file exists and then upon finding it, delete and then read from the log.

Otherwise, you might need to use OS commands to find out if your webserver is writing to the log and only run the log reader when it's not. http://blog.bensmann.com/executing-operating-system-commands has some good info on executing OS commands in Java.

Bottom line is there needs to be a solid gap of some sort established such that these processes aren't reading/writing to the log at the same time.




回答2:


I recently faced same issue, Let me explain when will bufferreader read incomplete line with readline() method. It will do this when it encounter EOF before carriage return.

The code in bufferedreader readine is like this

 if (nextChar >= nChars)
                    fill();
                if (nextChar >= nChars) { /* EOF */
                    if (s != null && s.length() > 0)
                        return s.toString();

                    else
                        return null;
                }

Which says that if it encounter EOF before carriage return it will return whatever it has already read. But correct code should be when we make call to readLine() and EOF character is encountered before carriage retunn it should return NULL instead of incomplete line.

I wrote my extended bufferedreader class in which ReadLine return NULL in scenario explained above.



来源:https://stackoverflow.com/questions/9436609/bufferedreader-readline-before-the-line-is-complete

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!