【问题标题】:Reading a gz file and keeping track of position in file读取 gz 文件并跟踪文件中的位置
【发布时间】:2011-03-06 12:53:47
【问题描述】:

所以,情况如下:

我必须阅读大的 .gz 档案 (GB) 并对它们进行某种“索引”,以便以后能够使用随机访问检索特定的片段。 换句话说,我希望逐行读取存档,并能够获取文件中任何此类行的特定位置。 (以便我可以根据要求直接跳转到这些特定位置)。 (PS:...而且它是 UTF-8,所以我们不能假设 1 字节 == 1 字符。)

所以,基本上,我只需要一个 BufferedReader 来跟踪它在文件中的位置。但是,这似乎不存在。

有什么可用的还是我必须自己推出?

一些额外的 cmets:

  • 我不能直接使用 BufferedReader,因为文件位置与目前缓冲的位置相对应。换句话说,是内部缓冲区大小的倍数,而不是行位置。
  • 出于性能原因,我不能直接使用 InputStreamReader。无缓冲会很慢,顺便说一句,缺乏读取行的便捷方法。
  • 我无法使用 RandomAccessFile,因为 1. 已压缩,2. RandomAccessFile 使用“修改后的”UTF-8

我想最好的办法是使用一种缓冲读取器来跟踪文件位置和缓冲区偏移量……但这听起来很麻烦。但也许我错过了什么。也许已经有一些东西可以做到这一点,逐行读取文件并跟踪位置(即使是压缩的)。

感谢您的提示,

阿诺

【问题讨论】:

    标签: java io


    【解决方案1】:

    我认为jzran 可能正是您想要的:

    这是一个基于 来自 zlib 的 zran.c 示例。

    你可以预处理一个大的 gzip 存档,生成一个“索引”,可以 用于随机读取访问。

    您可以在索引大小和 访问速度。

    【讨论】:

    • ...好吧,正如您所说,它实际上是通过访问 jna(本机访问库)来对 zran 库进行包装...所以它首先添加了几个依赖项:jzran、jna , zran 并且不再是真正的跨平台了。它也错过了像经典阅读器那样逐行读取的能力,但只是读取字节,所以您仍然必须转换为 UTF-8 字符。 ...我觉得这确实不是最佳解决方案
    • 如果您想要一个“一体化解决方案”,您必须自己编写。文件——尤其是压缩文件——总是在 Java 中以 InputStream 的形式处理。如果您希望它以字符形式使用,请使用 InputStreamReader。
    • 我同意罗伯特的观点。尽管如此,jzran 或自己的更跨平台的 zran.c 端口将是很好的起点,您可以添加诸如 UTF-8 解析之类的东西。
    • 嗯……这太疯狂了。 Java 已准备好所有成分(用于随机访问、解压缩 gzip 数据、缓冲、转换为 UTF-8 的类)......它们根本不结合在一起!!! io 和 nio 不共享任何通用接口简直太疯狂了。您想将 GZipInputStream 与 RandomAccessFile 一起使用吗?好吧,运气不好,你不能。 ...完全疯了。
    • @arnaud:嗯,gzip 不是为随机访问而设计的,像 zran.c 这样的东西是后来开发的,目的是为了获得类似于随机访问的东西,所以你不能真的责怪 Java 没有内置 gZip 随机访问类——仅仅结合 gZip 解压和随机访问根本行不通。
    【解决方案2】:

    您要查找的内容称为mark()、markSupported() 和skip()。

    该方法在 InputStream 和 Reader 中都有声明,欢迎大家使用。

    【讨论】:

    • 如果您想在之后将流重置回此位置,则使用标记。它不会为您提供有关位置本身的信息。
    【解决方案3】:

    GZIP 压缩不支持搜索。构建压缩表需要之前的数据块...

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-04-10
      • 1970-01-01
      • 2018-11-26
      • 1970-01-01
      • 1970-01-01
      • 2022-01-14
      相关资源
      最近更新 更多