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