Я хотел бы знать, каковы методы mark()
и reset()
BufferedReader
? Как их использовать? Я читал Джавадока, но, будучи новичком, я не мог этого понять.
Что такое mark и reset в BufferedReader?
Ответ 1
Методы потоков 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
уже поддерживает mark
и reset
самостоятельно! Потоки, которые считываются из источника данных в памяти, обычно поддерживают сами mark
и reset
, поскольку они уже имеют все данные в памяти, поэтому им легко их прочитать. Потоки, которые читаются из файлов или каналов или сетевых сокетов, естественно не поддерживают mark
и reset
, но вы всегда можете добавить эту функцию в любой поток, обернув ее в BufferedInputStream
или BufferedReader
.
Ответ 2
Значок mark()
, обозначающий определенную точку в потоке, и reset()
сбрасывает поток до последней метки. Эти методы предоставляют функцию book-marking
, которая позволяет вам читать вперед в потоке для проверки предстоящих данных.
Из этой документации:
Метод mark() помещает позицию на входе, к которой поток может быть "reset", вызывая метод reset(). Параметр readLimit - это число символы, которые можно прочитать из потока после установки знака перед знак становится недействительным. Например, если знак() вызывается с чтением предел 10, тогда, когда 11 строк данных считываются из потока до вызова метода reset(), то знак недействителен, и экземпляр объекта потока не требуется для запоминания метки. Обратите внимание, что количество символов, которые можно запомнить этим методом, может быть больше, чем размер внутреннего буфера чтения. Это также не в зависимости от подчиненного потока, поддерживающего метку/resetфункциональность.
Ответ 3
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
Ответ 4
Представьте, что у вас есть следующие символы в BufferReader = "123456789", если вы отметите в позиции 4 относительно "5" char, а затем reset ваш BufferReader, вы получите 12345.
Ответ 5
Интерфейс Reader не позволяет вам вернуться, вы можете просто прочитать. BufferedReader, с другой стороны, создает буфер, поэтому вы можете возвращать бит при чтении. И для этого нужны эти методы.
С помощью метода mark() вы помещаете "маркер" в позицию, после чего можете читать дальше. Как только вы осознаете, что хотите вернуть отмеченную позицию, вы используете для этого reset(). И с этого момента вы снова читаете те же ценности. Вы можете использовать его для всего, что хотите.