Чтение из большого постоянно растущего файла с помощью BufferedReader - PullRequest
9 голосов
/ 08 июля 2010

У меня есть задача (несколько эффективно) построчно читать очень большой, постоянно растущий файл.Вот в основном то, что я делаю сейчас:

BufferedReader rd = //initialize BufferedReader
String line;
while(true){
    while((line=rd.readLine())==null){
        try{
            Thread.sleep(1000);
        }catch(InterruptedException e){
            //handle exception
        }
    }
    //process line
}

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

Более конкретно, моя проблема возникает, когда происходит следующее чередование событий:

  1. Процесс записи записывает большую часть строки
  2. readLine () называется
  3. Процесс записи завершает эту строку и добавляет символ новой строки
  4. readLine () называется

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

Так что, по сути, необходимая мне функциональность - это BufferedReader, который возвращает ноль на одну readLine ранее;тот, который не дает вам строку, пока после нее не будет разрыв строки, а не просто EOF после нее.Поэтому, если он находит EOF, он не возвращает строку до этой точки, он возвращает ноль и возвращает эту строку, как только файл был записан, и после него есть новая строка.

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

Ответы [ 5 ]

2 голосов
/ 08 июля 2010

Вы можете начать с источника BufferedReader и переписать String readLine(boolean ignoreLF) метод, который вызывает проблему, если он находит EOF до конца строки. (К сожалению, он не может быть унаследован из-за объема пакета)

1 голос
/ 08 июля 2010

BufferedReader не должен возвращать ноль, пока не достигнет окончательного конца потока. Другими словами, я не ожидал бы, что когда-либо вернет ненулевое значение после того, как будет возвращено значение NULL.

Я немного удивлен, что он дает вам частичные строки - хотя я ожидаю, что он будет блокироваться, пока не будет полной строки.

0 голосов
/ 09 июля 2014

Как сказал stacker, лучшим способом было бы создать класс, унаследовавший Bufferedreader. Я обнаружил, что когда BufferedReader достиг EOF, он в значительной степени обречен. Если вы хотите продолжить чтение или проверить, есть ли что-то новое, вы всегда можете открыть и пропустить. На практике, если вы точно знаете, куда переходить, это не займет много времени. Посмотрите на ответ на этот вопрос. Он создал функцию reopenat () для читателя, чтобы читатель обновлялся.

Ошибка сброса BufferedReader после чтения до конца файла

0 голосов
/ 08 июля 2010

Старайтесь всегда толкать последнюю строку назад, используя устройство считывания с возвратом .

0 голосов
/ 08 июля 2010

Вы можете попробовать http://www.gnu.org/software/kawa/api/gnu/text/LineBufferedReader.html
Это дает вам возможность вернуться к началу строки

...