2015-03-05 3 views
1

Это мой код:Как вернуться в начало Bufferedreader?

public int Part1(BufferedReader reader) throws IOException{ 
     reader.mark(0); 
     int counter1 = 0; 
     String z; 
     while((z = reader.readLine()) != null){ 
      counter1 = counter1 + z.length(); 
     } 
     reader.reset(); // this is the error line 
     return counter1; 
    } 

Это код, чтобы подсчитать количество символов в файле. У меня есть другой алгоритм для запуска в той же программе, которая требует, чтобы BufferedReader возвращался в начало файла. Я посмотрел еще один ответ на StackOverFlow и пытался использовать метод mark() и reset(). Тем не менее, есть время выполнения ошибки:

Исключение в потоке «основной» java.io.IOException: поток не отмечен на java.io.BufferedReader.reset (Unknown Source)

Что здесь проблема ?

+0

Вы не можете. Потоки только идут вперед. Закройте и снова откройте файл. – immibis

ответ

3

Из документов для mark() параметр вы передаете к нему:

readAheadLimit - Limit on the number of characters that may be read while still preserving the mark. An attempt to reset the stream after reading characters up to this limit or beyond may fail. A limit value larger than the size of the input buffer will cause a new buffer to be allocated whose size is no smaller than limit. Therefore large values should be used with care.

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

Ваши варианты:

  • Вы можете передать размер файла, но внял предупреждение о больших значениях.

  • Повторное открытие файла и начать заново с новыми Reader с для каждого из методов (вы можете передать имя файла, к методам и пусть им справиться с ним, или открыть его на более высоком уровне и пройти новенький BufferedReader для каждого метода).

  • Используйте вместо этого FileChannel и его методы определения местоположения.

  • Используйте вместо этого метод поиска RandomAccessFile.

  • Переключение в InputStream s вместо Reader s (ум ваши кодировок) и, если основной поток является FileInputStream вы можете сбросить до начала использования его интерфейса канала, например:

    FileInputStream fileStream = ...; // once when you open the file 
    
    // For each method (us-ascii as example): 
    fileStream.getChannel().position(0); 
    BufferedReader reader = new BufferedReader(new InputStreamReader(fileStream, "us-ascii")); 
    // Use reader only in that method, resetting as above for each. 
    
0

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

+0

Если вы сделаете это, второй «BufferedReader» просто поднимет грузило, где первый остановился. –

0

Я предлагаю не перезагружать считывающее устройство, потому что читатель может сидеть на другом считывателе или потоке или файле, который также должен быть сброшен для работы. Это может привести к множеству проблем. Попробуйте сделать обе вещи одновременно или открыть еще один BufferedReader, но убедитесь, что потоки и считыватели под ним также свежи.

Когда вы читаете файл, вы можете ничего не получить, сбросив его. Может просто работать, как создание нового читателя.

+1

FYI, 'BufferedReader' не вызывает сброс базовых потоков. Вместо этого он использует параметр 'readAheadLimit'' mark() ', чтобы изменить размер входного буфера, чтобы он был достаточно большим во время отметки, затем он заполняет его, а не использует сброс потока поддержки.Вот почему знак признан недействительным, если после метки было прочитано больше байтов readAheadLimit. Предложение не использовать читателя по-прежнему остается хорошим, но по разным причинам. –

+0

Спасибо за отзыв. Проверьте код. Поэтому причина избежать перезагрузки - это, в основном, эти два комментария кода: «Последующие вызовы reset() ** будут пытаться ** переместить поток в эту точку ... Поэтому ** большие значения следует использовать с осторожностью **. «Поэтому ничто не приглашает нас использовать эту функцию вообще. – ReneS

+1

Да, механизм отметки/сброса в целом кажется мне довольно сомнительным (и плохо поддерживается - даже «FileReader» его реализует) в целом. Наверное, это одна из причин, по которой nio пошел с интерфейсом интерфейса SeekableByteChannel. –

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