如何制作BufferedReader的副本?

时间:2012-08-24 09:52:39

标签: java io bufferedreader

我正在使用BufferedReader构造函数制作现有BufferedReader的新副本。

BufferedReader buffReader = new BufferedReader(originalBuffReader);

新的buffReader工作正常,但当我originalBuffReader.readLine()时,它会给我null。还有其他方法可以制作新的bufferReader,而不会影响原来的BufferedReader

仅供参考:我将bufferReader作为我方法的输入;而我无权访问该来源。

3 个答案:

答案 0 :(得分:16)

  

我可以在不影响我的oroginal BufferReader的情况下制作新的bufferReader

通过创建两个BufferedReader来解决它没有直接的方法。 (这两个读者将使用来自同一来源的数据。)您必须在源上添加另一级别的缓冲,因此每个读者都可以独立读取流。

这可以通过组合来自Apache Commons的TeeInputStreamPipedInputStream以及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

答案 1 :(得分:2)

在构造函数中传入BufferedReader实例以获取新的BufferedReader将不会复制原始的BufferedReader!

你正在做的是链接两个读者,换句话说,你正在缓冲已经缓冲的读者实例。当您在readLine()上致电buffReader时,会在readLine()上致电originalBuffReader

在这里查看有关流链接的更多详细信息: Chaining of Streams

答案 2 :(得分:0)

以下是考虑从Original BufferedReader创建新的BufferedReader的一种方法。

基本上,我们将原始缓冲读取器的内容转储到字符串中,然后重新创建一个新的BufferedReader对象。为了能够再次读取原始的BufferedReader,您可以对其进行标记,然后在读取之后,您可以重置它。

要记住的一件事是你可能想要通过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())));