如何制作 BufferedReader 的副本?
Posted
技术标签:
【中文标题】如何制作 BufferedReader 的副本?【英文标题】:How can I make a copy of a BufferedReader? 【发布时间】:2012-08-19 21:05:58 【问题描述】:我正在使用BufferedReader
构造函数来制作现有BufferedReader
的新副本。
BufferedReader buffReader = new BufferedReader(originalBuffReader);
新的buffReader
工作正常,但是当我使用originalBuffReader.readLine()
时,它给了我null
。有没有其他方法可以在不影响我原来的BufferedReader
的情况下创建一个新的bufferReader
。
仅供参考:我将 bufferReader 作为方法的输入;而且我无权访问源代码。
【问题讨论】:
“BufferedReader 的副本”到底是什么意思?您是否期望以某种方式能够两次读取相同的流?这是不可能的。事实上,这是一个矛盾的术语。 【参考方案1】:我可以通过任何其他方式制作新的 bufferReader 而不会影响我原来的 BufferReader
没有直接的方法可以通过创建两个BufferedReader
s 来解决它。 (两个读取器将使用来自同一源的数据。)您必须在源上添加另一层缓冲,以便每个读取器可以独立读取流。
这可以通过组合来自 Apache Commons 的 TeeInputStream
和 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
【讨论】:
感谢 aioobe 的回复,实际上我正在获取一个 bufferReader 作为我的方法的输入,所以我必须使用该 bufferReader 进行复制,因为它无法访问源代码。 然后我会创建一个包装器来包装给定的缓冲阅读器,缓冲读取行并处理从缓冲区读取的辅助阅读器。 (除非您可以选择将数据完全排入 ListClassLoader.getSystemResourceAsStream("myResource")
,它将被卡住。【参考方案2】:
以下是考虑从原始 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())));
【讨论】:
【参考方案3】:在构造函数中为新的BufferedReader
传递BufferedReader
实例不会复制原始的BufferedReader!
你正在做的是链接两个阅读器,换句话说,你正在缓冲已经缓冲的阅读器实例。当你在buffReader
上调用readLine()
时,它会在originalBuffReader
上调用readLine()
。
在此处查看有关流链接的更多详细信息: Chaining of Streams
【讨论】:
以上是关于如何制作 BufferedReader 的副本?的主要内容,如果未能解决你的问题,请参考以下文章