2011-11-23 3 views

ответ

1

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

С помощью метода mark() вы помещаете «маркер» в позицию, после чего можете читать дальше. Когда вы поймете, что хотите вернуть отмеченную позицию, для которой вы используете reset(). И с этого момента вы снова читаете те же ценности. Вы можете использовать его для всего, что хотите.

1

Представьте, что вы имеете следующие символы в Передней BufferReader = «123456789», если вы отмечаете в положении 4 по отношению к полукокса в «5», то сбросить BufferReader вы будете в конечном итоге с 12345.

+1

Это половина ответа, и тем, что сброс? – eeerahul

+0

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

13

mark и reset методы потоков обеспечивают способ перехода назад в поток и перечитывание данных.

Когда вы вызываете mark() на BufferedReader, он начнет хранить данные, которые вы читаете с этой точки, в своем внутреннем буфере. Когда вы вызываете reset(), он возвращается к отмеченной позиции потока, поэтому следующий read() s будет удовлетворен буфером в памяти. Когда вы прочтете за конец этого буфера, он будет легко вернуться к чтению свежих данных. BufferedInputStream работает одинаково.

Параметр int для mark сообщает ему максимальное количество символов (для BufferedReader) или байтов (для BufferedInputStream), которые вы хотите, чтобы иметь возможность вернуться назад. Если вы читаете слишком много данных за отмеченной позицией, то знак может быть «недействительным», а вызов reset() завершится с ошибкой.

Небольшой пример:

BufferedReader r = new BufferedReader(new StringReader(
    "Happy Birthday to You!\n" + 
    "Happy Birthday, dear " + System.getProperty("user.name") + "!")); 
r.mark(1000); // save the data we are about to read 
System.out.println(r.readLine()); // read the first line 
r.reset(); // jump back to the marked position 
r.mark(1000); // start saving the data again 
System.out.println(r.readLine()); // read the first line again 
System.out.println(r.readLine()); // read the second line 
r.reset(); // jump back to the marked position 
System.out.println(r.readLine()); // read the first line one final time 

В этом примере, я завернул StringReader в BufferedReader, чтобы получить метод readLine(), но StringReader s уже поддерживают mark и reset сами по себе! Потоки, которые считываются с источника данных in-memory, обычно поддерживают mark и reset, поскольку они уже имеют все данные в памяти, поэтому им легко их прочитать. Потоки, которые читаются из файлов или труб или сетевых сокетов, естественно не поддерживают mark и reset, но вы всегда можете добавить эту функцию в любой поток, обернув ее в BufferedInputStream или BufferedReader.

+0

и что это за параметр в mark()? – UnKnown

+0

@UnKnown Я расширил ответ – Boann

8

mark() Маркировка определенной точки в потоке и reset() сбрасывает поток до последней отметки. Эти методы предоставляют функцию book-marking, которая позволяет вам читать вперед в потоке для проверки предстоящих данных.

Из этого documentation:

знака() метода отметить позицию во входном потоке, к которому поток может быть «сбросить» с помощью вызывающего метода сброса().Параметр readLimit представляет собой число символов , которые могут быть считаны из потока после установки знака до . Знак становится недействительным. Например, если вызов mark() вызывается с префиксом с чтением, то, когда перед вызовом метода reset() считывается 11 символов данных из потока , то метка недействительна, а объект объекта потока не требуется помнить отметку. Обратите внимание, что количество символов, которое может быть запомнено этим методом, может быть больше, чем размер внутреннего буфера чтения. Это также не в зависимости от подчиненного потока, поддерживающего знак/сброс .

+0

вы также можете просто использовать это, чтобы просто отметить начало и вернуться к началу, чтобы перечитать буфер? например, если вы хотите дважды прочитать файл. один раз, чтобы получить контекст, вернитесь к началу, затем снова прочитайте? – anon58192932

+0

и что это за параметр? – UnKnown

6

Reader::mark(int readLimit) документация говорят:

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

Пример:

import java.io.*; 
import static java.lang.System.out; 

public class App { 

    public static final String LINE = "Line 1\nLine 2\nLine 3\nLine 4\n"; 

    public static void main(String[] args) { 

     try (BufferedReader in = new BufferedReader(new StringReader(LINE))) { 

      // first check if this Reader support mark operation 
      if (in.markSupported()) { 

       out.println(in.readLine()); 
       in.mark(0);      // mark 'Line 2' 
       out.println(in.readLine()); 
       out.println(in.readLine()); 
       in.reset();      // reset 'Line 2' 
       out.println(in.readLine()); 
       in.reset();      // reset 'Line 2' 
       out.println(in.readLine()); 
       in.mark(0);      // mark 'Line 3' 
       out.println(in.readLine()); 
       in.reset();      // reset 'Line 3' 
       out.println(in.readLine()); 
       out.println(in.readLine()); 
      } 
     } catch (IOException e) { 
      e.printStackTrace(); 
     } 
    } 
} 

Выход:

Line 1 
Line 2 
Line 3 
Line 2 
Line 2 
Line 3 
Line 3 
Line 4 
+0

Как вы можете вызвать 'reset()'? Я думал, что если вы 'mark()' с пределом чтения 0, как только один символ будет прочитан, маркер станет недействительным, и невозможно вызвать сброс. Вы можете объяснить свой ответ? – snooze92

+0

@ snooze92 Просто для запуска этого примера и попытайтесь изменить аргумент 'markLimit' в методе' mark'. У вас будет тот же результат все время. Также см. Аналогичные примеры: [1] (http://goo.gl/KxU1Fy), [2] (http://goo.gl/S2R3qd). Я действительно хотел задать вопросы о том, что кто-то дал мне объяснение по этому поводу. –

+2

После запуска большего количества собственных примеров, я немного понимаю механизм '' (readAheadLimit) '/' reset() 'немного лучше. В принципе, метод 'mark' просто отмечает точку в ** текущем буфере **, а' reset' позволяет вернуться к этой отмеченной точке. Дело в том, что оно не предназначено для отметки точки в файле или потоке, так как необходимо увеличить размер буфера, чтобы иметь возможность доступа к отмеченной точке. Вот почему один * должен * использовать предел, который относительно меньше размера буфера. – snooze92

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