Как я могу сделать копию BufferedReader?

Я использую конструктор BufferedReader, чтобы создать новую копию существующего BufferedReader.

BufferedReader buffReader = new BufferedReader(originalBuffReader);

Новый buffReader работает нормально, но когда я делаю originalBuffReader.readLine(), он дает мне null. Есть ли другой способ создать новый bufferReader, не влияя на исходный BufferedReader.

FYI: я получаю bufferReader в качестве ввода моего метода; и у меня нет доступа к источнику.

Ответ 1

любым другим способом я могу создать новый bufferReader, не влияя на мой oroginal BufferReader

Нет прямого пути решения этого вопроса, просто создав два BufferedReader s. (Два считывателя будут потреблять данные из того же источника.) Вам придется добавить еще один уровень буферизации в источнике, поэтому каждый читатель может самостоятельно прочитать поток.

Это может быть достигнуто путем объединения TeeInputStream из Apache Commons и PipedInputStream и PipedOutputStream следующим образом:

import java.io.*;
import org.apache.commons.io.input.TeeInputStream;
class Test {
    public static void main(String[] args) throws IOException {

        // Create the source input stream.
        InputStream is = new FileInputStream("filename.txt");

        // Create a piped input stream for one of the readers.
        PipedInputStream in = new PipedInputStream();

        // Create a tee-splitter for the other reader.
        TeeInputStream tee = new TeeInputStream(is, new PipedOutputStream(in));

        // Create the two buffered readers.
        BufferedReader br1 = new BufferedReader(new InputStreamReader(tee));
        BufferedReader br2 = new BufferedReader(new InputStreamReader(in));

        // Do some interleaved reads from them.
        System.out.println("One line from br1:");
        System.out.println(br1.readLine());
        System.out.println();

        System.out.println("Two lines from br2:");
        System.out.println(br2.readLine());
        System.out.println(br2.readLine());
        System.out.println();

        System.out.println("One line from br1:");
        System.out.println(br1.readLine());
        System.out.println();
    }
}

Вывод:

One line from br1:
Line1: Lorem ipsum dolor sit amet,      <-- reading from start

Two lines from br2:
Line1: Lorem ipsum dolor sit amet,      <-- reading from start
Line2: consectetur adipisicing elit,

One line from br1:
Line2: consectetur adipisicing elit,    <-- resumes on line 2

Ответ 2

Передача экземпляра BufferedReader в конструкторе для нового BufferedReader не сделает копию исходного BufferedReader!

Что вы делаете, так это цепочка двух считывателей, другими словами, вы буферизуете уже буферизованный экземпляр читателя. Когда вы вызываете readLine() на buffReader, он будет вызывать readLine() на originalBuffReader.

Взгляните сюда на более подробные сведения о цепочке потоков: Цепочка потоков

Ответ 3

Ниже приведен один из способов рассмотреть возможность создания нового BufferedReader из исходного BufferedReader.

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

Следует иметь в виду, что вы можете защитить от DDOS-атак, в которые может войти очень большой буферный читатель, и вы, возможно, захотите избежать чтения навсегда и заполнить память, вы можете в принципе разбить цикл for после некоторой точки или когда выполняется определенное условие.

final String originalBufferedReaderDump;
originalBufferedReaderDump.mark(Integer.MAX_VALUE);
for (String line; (line = originalBufferedReader.readLine()) != null; originalBufferedReaderDump+= line);
originalBufferedReader.reset();
final BufferedReader copiedBufferedReader  = new BufferedReader(new InputStreamReader(new ByteArrayInputStream(originalBufferedReaderDump.getBytes())));