3

编辑:我真的只需要知道 Deflater 派生类何时决定写入页眉和页脚数据,以及如何利用这些事实。我真的很想做以下事情:

  1. 为 Deflater 派生类添加一些字节的字典(我想我明白了)。

  2. 将一些要压缩的数据发送到 Deflater 派生类(我想我明白了)。

  3. 将所有压缩数据(没有页眉或页脚数据)输出到我想要的任何地方(不确定如何执行此操作,也可以同时拥有页眉/页脚,或者只有一个,只要它是一致的) .

  4. 从 1 重新开始重用对象。

原问:我正在使用 Java DeflaterOutputStream 来压缩一些数据。我还通过修改页眉和页脚来修改这些压缩数据。我想给 DeflaterOutputStream 一些输入,让它只输出压缩数据部分,而不是 gzip 格式的页眉或页脚。我该怎么做?

到目前为止,我一直在尝试做这样的事情:

internalWriter.write(storage, 0, amountRead);
internalWriter.finish();
internalWriter.getDef().reset();

这里的 internalWriter 是 DeflaterOutputStream 的扩展。这将输出带有页眉和页脚的压缩数据。但是,在使用相同对象的后续调用中,它会输出压缩数据和页脚。我基本上只想要压缩数据,或者每次都发生同样的事情。有任何想法吗?对压缩流如何使用 close、flush、finish 的快速解释也可能对我有所帮助,重点是何时创建和输出页眉和页脚。

每次我使用 DeflaterOutputStream 时,我都希望它立即输出所有内容。这就是为什么我在上面看到的右边之后完成了...

4

3 回答 3

3

你可以在Java Almanac中看到很好的例子

- - 编辑 - -

让我尝试提供更多帮助。Elliote Rusty Harold所著的Java I/O一书可能是我找到的最好的参考书。您可以从 OReilly Books 获得它。我将为您提供书中的一些引用和示例。

缩小数据

Deflater 类包含压缩数据块的方法。您可以选择压缩格式、压缩级别和压缩策略。使用 Deflater 类对数据进行放气需要九个步骤:

  1. 构造一个 Deflater 对象。
  2. 选择策略(可选)。
  3. 设置压缩级别(可选)。
  4. 预设字典(可选)。
  5. 设置输入。
  6. 重复压缩数据,直到 needsInput( ) 返回 true。
  7. 如果有更多输入可用,请返回步骤 5 以提供其他输入数据。否则,转到步骤 8。
  8. 完成数据。
  9. 如果有更多流需要放气,请重置放气器。

通常,您不直接使用此类。相反,您可以通过 DeflaterInputStream 或 DeflaterOutputStream 等压缩流类之一间接使用 Deflater 对象。这些类为面向流的压缩提供了比原始 Deflater 方法更方便的程序员接口。

膨胀数据

  1. 构造一个 Inflater 对象。
  2. 使用要膨胀的压缩数据设置输入。
  3. 调用 needsDictionary( ) 来确定是否需要预设字典。
  4. 如果 needsDictionary() 返回 true,调用 getAdler() 获取字典的 Adler-32 校验和。然后调用 setDictionary() 来设置字典数据。
  5. 反复膨胀数据,直到 inflate( ) 返回 0。
  6. 如果 needsInput( ) 返回 true,则返回步骤 2 以提供额外的输入数据。
  7. finished() 方法返回 true。

现在,这本书用一整章的时间来压缩和解压缩数据,我认为这里不可能全部解释清楚。您必须完成任务的一部分,如果需要,请提出一个更狭窄的问题。

于 2012-10-24T23:51:53.250 回答
2

请参阅deflater (sic) 文档。如果nowrap为真,则不会生成标头或尾标——只有deflate 格式的原始压缩数据。

于 2012-10-25T02:53:57.037 回答
1

听起来您想要有两个流,您的目标流,然后是装饰目标流的压缩器流。然后,您会将未压缩的数据写入基本流,将压缩数据写入装饰器流。确保在切换之前冲洗。读取将是一个类似的过程,但您需要知道压缩数据在流中的开始和结束位置。

假设目标流是一个文件,类似于以下伪代码...

    FileOutputStream dest = new FileOutputStream(foo);
    DeflaterOutputStream decorator = new DeflaterOutputStream(dest);

    byte[] header = getHeader();
    byte[] body = getBody();
    byte[] footer = getFooter();

    dest.write(header);
    dest.flush();
    decorator.write(body);
    decorator.flush();
    dest.write(footer);

我想知道是否DeflaterOutputStream真的是你想要的。那不是zip文件的一部分吗?如果您正在做一些自定义的事情,似乎您只想对其进行 gzip 压缩。

于 2012-10-25T01:42:53.817 回答