在 Java 中多次从 BufferedReader 读取
Posted
技术标签:
【中文标题】在 Java 中多次从 BufferedReader 读取【英文标题】:Read from a BufferedReader more than once in Java 【发布时间】:2014-02-09 19:49:22 【问题描述】:我有以下 Java 代码:
HttpURLConnection con = (HttpURLConnection)new URL(url).openConnection();
con.connect();
InputStream stream = con.getInputStream();
BufferedReader file = new BufferedReader(new InputStreamReader(stream));
此时,我在搜索内容时从头到尾读取文件:
while (true)
String line = file.readLine();
if (line == null)
break;
// Search for something...
现在我想在文件中搜索其他内容,无需打开另一个 URL 连接。
由于与此问题无关的原因,我希望避免“在单个文件扫描中”搜索这两个东西。
问题:
我可以使用reset
倒带文件吗?
如果是,我应该将其应用于InputStream
对象、BufferedReader
对象还是同时应用于这两者?
如果不是,我应该直接关闭文件并重新打开它吗?
如果是,我应该将其应用于InputStream
对象、BufferedReader
对象还是同时应用于这两者?
如果没有,我怎么能再次扫描文件,而无需再次读取 URL 连接?
【问题讨论】:
将InputStream
读入ByteArrayInputStream
并从中重新读取。
【参考方案1】:
我通常最终使用InputStreamSource 之类的东西来方便重新阅读。当我处理连接时,我发现使用内存或磁盘假脱机策略进行重新读取很有用。使用阈值来选择存储位置,在第一次读取时“tee”进入假脱机,并在后续读取时从假脱机重新读取。
编辑:还发现了具有相同目的的番石榴ByteSource和CharSource。
【讨论】:
【参考方案2】:使用以下方法:
mark
skip
reset
只有当markSupported()
返回true
时,您才能执行此操作。请注意,实际上 reader 通常不会添加此功能,而是将其委托给包装的输入流,因此请始终调用 markSupported()
并记住它可以为不支持此功能的流返回 false
。
例如,基于 URL 的流确实会发生这种情况:想想,如何重置源自远程服务器的流。这可能需要客户端缓存您已经下载的所有内容。
【讨论】:
根据文档,BufferedReader 有自己的缓冲区,并且始终支持 mark()。 你是对的。但据我所知,它受到 64K 或更多的限制,但无论如何它不是无限的。从外部进程的输出流读取时遇到了这个问题。 我明白了。然而,javadoc 只是说:A limit value larger than the size of the input buffer will cause a new buffer to be allocated whose size is no smaller than limit. Therefore large values should be used with care.
广告中没有“limit
的限制”,但是我认为这是一个设计不当的过程,我建议 OP 重新考虑他/她的设计。【参考方案3】:
您可以使用reset()
倒带文件,前提是您已将mark()
设置为您想要倒带到的位置。这些方法应该在装饰器上调用,即BufferedReader
。
但是,您可能需要重新考虑您的设计,因为您可以轻松地将整个文件读入某个数据结构(甚至是字符串列表,或由字符串支持的某个流)并多次使用该数据。
【讨论】:
所以我只需要在第一次扫描之前file.mark(some large value)
,在第二次扫描之前file.reset()
?
没错。但我仍然鼓励你重新考虑你的设计。
好的,抱歉。我们同时编写了两个 cmets。以上是关于在 Java 中多次从 BufferedReader 读取的主要内容,如果未能解决你的问题,请参考以下文章
java中BufferedReader和FileReader怎么用?