Подтвердить что ты не робот

Что такое mark и reset в BufferedReader?

Я хотел бы знать, каковы методы mark() и reset() BufferedReader? Как их использовать? Я читал Джавадока, но, будучи новичком, я не мог этого понять.

4b9b3361

Ответ 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(). И с этого момента вы снова читаете те же ценности. Вы можете использовать его для всего, что хотите.