【问题标题】:Append to a compressed stream with Java使用 Java 附加到压缩流
【发布时间】:2015-08-01 05:53:24
【问题描述】:

我们目前有一些数据日志。日志是仅追加的,但在每次追加时,都会从头开始扫描整个日志以进行一些一致性检查(某些事件组合会触发警报)。

现在,我们想将该日志转换为压缩日志。单个日志条目通常只有几十个字节,因此它们不会很好地压缩。但是,整个日志流确实压缩得很好,存在足够的冗余。

理论上,应用到压缩流应该很容易,因为可以在扫描(和解压缩)日志时重建压缩编码器的状态。

我们目前的方法是在扫描和解压缩阶段运行具有相同设置的压缩器,并为其提供刚刚解压缩的数据(假设它将构建相同的状态)。

但是,我们知道这不是最优的。我们想重用在解压过程中构建的状态来压缩新数据。所以问题是:我们如何实现(解)压缩,我们不需要将解压缩的数据提供给压缩器来构建状态,而是可以重新使用解压缩器的状态来压缩新数据我们追加?

(不幸的是,我们需要在 java 中执行此操作,这限制了可用 API 的数量。但是,可以选择包含免费/开源的 3rd 方代码。)

【问题讨论】:

  • 听起来像是一个计划。这一切有什么问题?
  • 问题是如何实现(解)压缩,我们不需要将解压后的数据提供给压缩器来构建状态,而只需重新使用解压器的状态压缩我们附加的数据。
  • 难道你不只是破解 gzip 的实现,以添加一个方法来允许压缩器实例复制解压缩器实例的状态吗?
  • @Atsby:这是一个可能的解决方案——但是,由于我们有 java,我们不能直接访问 gzip。而且,老实说,将这样的功能入侵到没有考虑到该要求的压缩器实现的内部并不是那么容易,而且您破坏某些东西的风险很高。
  • 我的意思是 gzip 的 Java 实现......也许 jzlib 会是一个很好的目标。我严重怀疑那里有一个默认情况下具有这种功能的库。

标签: java stream compression append


【解决方案1】:

您可能没有在 Java 中需要的接口,但这可以通过 zlib 来完成。你可以为 zlib 编写自己的 Java 接口来做到这一点。

扫描时,您将使用队列保留最后 32K 的未压缩数据。您将使用inflate() 中的Z_BLOCK 扫描压缩文件。这将在每个放气块停止。当您到达由块的第一位标识的最后一个块时,您将保存该块的未压缩数据,以及您在队列中保存的它之前的 32K 数据。您还将保存前一个块中未完成字节的最后一位(0..7 位)。然后,您可以将新的日志条目添加到最后一块未压缩的数据中,然后使用前面带有 deflateSetDictionary() 的 32K 重新压缩该部分。您可以使用deflatePrime() 在位边界上开始压缩。这将用新的压缩块或块覆盖最后一个压缩块。

【讨论】:

    猜你喜欢
    • 2016-12-03
    • 1970-01-01
    • 1970-01-01
    • 2013-08-16
    • 1970-01-01
    • 2016-06-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多