Java BufferedReader вернуться к началу текстового файла? - PullRequest
26 голосов
/ 04 ноября 2008

У меня в настоящее время есть 2 BufferedReader s, инициализированные в том же текстовом файле. Когда я закончу читать текстовый файл с первым BufferedReader, я использую второй, чтобы сделать еще один проход через файл сверху. Необходимо несколько проходов через один и тот же файл.

Я знаю о reset(), но ему должен предшествовать вызов mark(), а mark() нужно знать размер файла, что, я думаю, не должно беспокоить.

Идеи? Пакеты? Libs? Код

Спасибо TJ

Ответы [ 5 ]

29 голосов
/ 04 ноября 2008

Буферизированные считыватели предназначены для последовательного чтения файла. То, что вы ищете, это java.io.RandomAccessFile , и затем вы можете использовать seek(), чтобы доставить вас туда, куда вы хотите в файле.

Устройство чтения с произвольным доступом реализовано так:

try{
     String fileName = "c:/myraffile.txt";
     File file = new File(fileName);
     RandomAccessFile raf = new RandomAccessFile(file, "rw");
     raf.readChar();
     raf.seek(0);
} catch (FileNotFoundException e) {
     // TODO Auto-generated catch block
     e.printStackTrace();
} catch (IOException e) {
     // TODO Auto-generated catch block
     e.printStackTrace();
}

"rw" - символ режима, который подробно описан здесь .

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

25 голосов
/ 04 ноября 2008

В чем недостаток простого создания нового BufferedReader для чтения сверху? Я ожидаю, что операционная система кеширует файл, если он достаточно мал.

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

3 голосов
/ 04 ноября 2008

Лучший способ продолжить - изменить свой алгоритм так, чтобы вам НЕ понадобился второй проход. Я использовал этот подход пару раз, когда мне приходилось иметь дело с огромными (но не ужасными, то есть несколькими ГБ) файлами, которые не помещались в доступную память.

Это может быть сложно, но увеличение производительности обычно стоит усилий

1 голос
/ 05 ноября 2008

Об отметке / сбросе:

Метод mark в BufferedReader принимает параметр readAheadLimit, который ограничивает, насколько далеко вы можете прочитать после метки, прежде чем сброс становится невозможным. Сброс на самом деле не означает поиск файловой системы (0), он просто ищет внутри буфера. Процитирую Javadoc:

readAheadLimit - Ограничение на количество символов, которые могут быть прочитаны при сохранении отметки. После прочтения этого большого количества символов попытка сброса потока может завершиться неудачей. Значение предела, превышающее размер входного буфера, приведет к тому, что будет выделен новый буфер, размер которого не меньше предела. Поэтому большие значения следует использовать с осторожностью.

0 голосов
/ 04 ноября 2008

"Весь бизнес о mark () и reset () в BufferedReader попахивает плохим дизайном."

почему бы вам не расширить этот класс и не сделать так, чтобы он делал mark () в конструкторе (), а затем выполнял поиск (0) в методе topOfFile ().

BR
~ A

...