2012-02-24 5 views
0

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

Тогда у меня есть отдельный процесс, который считывает файл журнала как (хвост -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 не является полной строкой. Полагаю, это потому, что автор (веб-сервер) еще не закончил сбрасывать все байты строки в файл.

Любые предложения по исправлению или обо всем этом? Большое спасибо!

+0

У вас есть шаблон для обнаружения, когда линия не завершена? – VirtualTroll

+0

Просто быстрый указатель: вам не нужно использовать 'while (true) ... break', вы можете использовать переменную, чтобы проверить, следует ли продолжить. – Viruzzo

+0

Я думаю, что это могло бы вам помочь: http://docs.oracle.com/javase/1.4.2/docs/api/java/io/FileDescriptor.html#sync() – nullpotent

ответ

1

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

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

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

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

+0

Спасибо Зак. Веб-сервер пишет довольно быстро, пару строк и куб kB каждую секунду, и он растет. Не уверен, будет ли дорого проверять, выполняется ли веб-сервер. На самом деле, я не думаю, что читатель немного отстает от писателя, если это помогает, но не знает, как это сделать. –

-1

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

Код в BufferedReader 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 в сценарии, описанном выше.

+1

Что такое символ EOF? –

+0

В коде, о котором вы указали символ EOF, ничего нет. Нет EOF-символа. Существует условие EOF *. * – EJP

Смежные вопросы