在 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 读取

java —— 异常中的陷阱

java中BufferedReader和FileReader怎么用?

用Java对CSV文件进行读写操作

Java 列表项在页面重新加载时重新添加到 thymeleaf 下拉列表中,多次出现

如果在 PDF 表单中多次出现,Java PDFBox 不会保持字段的字体外观