BufferedReader readLine до завершения строки - PullRequest
0 голосов
/ 24 февраля 2012

У меня есть процесс (на самом деле веб-сервер), который записывает в файл журнала как POST, приходящий от клиентов.

Затем у меня есть отдельный процесс, который читает файл журнала как (tail -f) вцикл:

            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;
                    }
            }

Это работает очень хорошо в 99% случаев, но иногда строка, которую я прочитал с помощью BufferedReader.readLine, не является полной строкой.Я полагаю, это потому, что писатель (веб-сервер) еще не завершил сброс всех байтов строки в файл.

Есть предложения, чтобы исправить это или обойти это?Большое спасибо!

Ответы [ 2 ]

1 голос
/ 25 февраля 2012

Работая с несколькими процессами, которым требуется доступ к одному файлу примерно в одно и то же время (часто один процесс сразу за другим), я обнаружил (вместе с другими разработчиками, с которыми работал), что файл "трейлера"полезно использовать для указания, когда один процесс завершает взаимодействие с файлом, к которому должен обращаться другой процесс.

Я не уверен, как часто ваш веб-сервер записывает в этот журнал, а также как быстро ваш Java-процессНеобходимо прочитать его, но если между доступом каждого файла к файлу может пройти промежуток времени, может быть записан файл трейлера, который указывает, когда ваш веб-сервер завершил запись в файл.Ваш Java-процесс может сначала проверить, существует ли файл трейлера, а затем, найдя его, удалить и затем прочитать из журнала.

В противном случае вам может понадобиться использовать команды ОС, чтобы выяснить, выполняет ли ваш веб-сервер запись ввойти и только запустить программу чтения журнала, когда это не так.http://blog.bensmann.com/executing-operating-system-commands содержит некоторую полезную информацию о выполнении команд ОС в Java.

Суть в том, что должен быть какой-то определенный пробел, установленный таким образом, что эти процессы не читают / записывают в журналв то же время.

0 голосов
/ 21 декабря 2012

Я недавно столкнулся с той же проблемой, позвольте мне объяснить, когда будет читатель буфера считывает неполную строку с readline () метод. Это будет сделано, когда он встретит EOF перед возвратом каретки.

Код в буфере читателя readine выглядит так

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

                    else
                        return null;
                }

Что говорит о том, что если он столкнется с EOF до возврата каретки, он вернет все, что уже прочитал. Но правильный код должен быть, когда мы выполняем вызов readLine (), и перед повторным переносом каретки встречается символ EOF, он должен возвращать NULL вместо неполной строки.

Я написал свой расширенный класс bufferedreader, в котором ReadLine возвращает NULL в сценарии, описанном выше.

...