【问题标题】:Read lines from Java FileInputStream without losing my place从 Java FileInputStream 读取行而不丢失我的位置
【发布时间】:2013-09-28 13:49:00
【问题描述】:

我有一个 FileInputStream。我想从中读取面向字符的逐行数据,直到找到特定的分隔符。然后我想将 FileInputStream(当前位置设置在分隔符行末尾之后)传递给需要 InputStream 的库。

我可以使用 BufferedReader 一次遍历文件一行,一切正常。但是,这会将底层文件流留在

BufferedReader br = new BufferedReader(new InputStreamReader(myFileStream))

在一个不确定的位置 - BufferedReader 必须向前看,我不知道多远,而且 AFAICT 没有办法告诉 BufferedReader 将底层流倒回到最后返回的行之后。

this 是最好的解决方案吗?拥有ReaderInputStream(BufferedReader(InputStreamReader(FileInputStream))) 似乎很疯狂,但这是我见过的唯一避免自己滚动的方法。如果可能的话,我真的很想避免编写我自己的整个流式读取行实现。

【问题讨论】:

  • 为什么不使用Channel
  • 你考虑过InputStream.mark, reset, markSupported吗?不过有点麻烦。也许用计数器保持位置,关闭文件,然后使用skip(position - 1) 左右。
  • 鲍里斯:频道有什么帮助?我基本上想要一个实现 InputStream 的类,并且有一个readLine() 方法。除此之外,我想要一个具有readLine() 方法和InputStream 构造函数的类,在每次readLine() 调用后将传递的流留在“正确”位置。

标签: java stream bufferedreader


【解决方案1】:

您不能取消缓冲缓冲的阅读器。您必须在应用程序的生命周期中使用相同的包装器。在你的情况下,我会使用

DataInputStream dis = new DataInputStream(new BufferedInputStream(new FileInputStream(file)));

String line = dis.readLine();

虽然 DataInputStream.readLine() 已被弃用,但如果你小心的话,它可能对你有用。否则,您唯一的选择是自己读取字节并使用所需的编码解析文本。

【讨论】:

  • 如果您的缓冲阅读器可以保证底层流支持标记,那么在读取一行之前标记很简单,读取该行,倒退到标记,然后跳过向前行的长度 - presto,底层流在“正确”的位置。现在,仅仅因为我说它简单就意味着我想自己构建、测试和维护它:-/
  • @Coderer 但是你什么时候标记()? BufferedReader 可能在过去的任何时间都读取了您想要停止的行(或行的一部分)。您无法保证您所标记的内容。问题是在调用用于执行此操作的 BufferedReader 之前,您必须解析每行结束的位置,知道标记的位置。
  • @Coderer 如果您对协议有任何控制权,我会将其设为纯二进制协议,并且不会出现此问题。
  • 我没有。我正在读取一个具有可变数量的标题行的文件,然后是 Base64 编码的数据。我想阅读标题行,然后将 base64 编码文本流传递给 Commons-Codec Base64InputStream 构造函数。我无法更改文件格式,我希望尽可能少地编写/维护处理逻辑。
  • 我开始认为ReaderInputStream 是要走的路——Base64InputStream 真的应该有一个 Reader 构造函数,因为 Base64 编码的东西真的是可打印字符。既然它没有,我认为下一个最好的办法是给它一个实际上基于字符的 InputStream,这就是 ReaderInputStream 所做的。
猜你喜欢
  • 1970-01-01
  • 2018-06-09
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-05-25
  • 1970-01-01
  • 1970-01-01
  • 2015-07-11
相关资源
最近更新 更多