如何使用Java DeflaterOutputStream

时间:2012-10-24 23:42:13

标签: java gzip

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

  1. 使用一些字节为Deflater派生类填充字典(我想我得到了这个)。

  2. 发送一些要压缩的数据到Deflater派生类(我想我得到了这个)。

  3. 将所有压缩数据(没有头文件或脚本数据)输出到我想要的任何地方(不知道怎么做,也可以同时使用页眉/页脚,或者只有一个,就像只要它是一致的。)

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

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

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

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

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

    每次我使用DeflaterOutputStream时,我希望它立即输出所有内容。这就是为什么我在右上方完成了如上所示的结束......

3 个答案:

答案 0 :(得分:4)

您可以在Java Almanac

中看到很好的例子

---编辑---

让我尝试多一点帮助。 Elliote Rusty Harold的书Java I/O也许是我发现的最佳参考书。你可以从OReilly Books获得它。我将从书中为您提供一些引用和示例。

缩小数据

  

Deflater类包含压缩数据块的方法。您   可以选择压缩格式,压缩级别和   压缩策略。使用Deflater类来限制数据需要   九个步骤:

     
      
  1. 构建一个Deflater对象。
  2.   
  3. 选择策略(可选)。
  4.   
  5. 设置压缩级别(可选)。
  6.   
  7. 预设字典(可选)。
  8.   
  9. 设置输入。
  10.   
  11. 反复放样数据,直到needsInput()返回true。
  12.   
  13. 如果有更多输入,请返回步骤5以提供其他输入数据。否则,请转到步骤8.
  14.   
  15. 完成数据。
  16.   
  17. 如果有更多的流要放气,请重置deflater。
  18.         

    通常,您不直接使用此类。相反,你   通过其中一个压缩流间接使用Deflater对象   像DeflaterInputStream或DeflaterOutputStream这样的类。这些   类提供更方便的程序员接口   面向流的压缩比原始的Deflater方法。

膨胀数据

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

现在,本书专门用了整整一章来压缩和解压缩数据,我认为不可能在这里解释一下。你必须完成任务的一部分,如果需要,可以回答一个较窄的问题。

答案 1 :(得分:2)

请参阅deflater(原文如此)文档。如果nowrap为真,那么就没有生成标题或预告片 - 只有deflate format中的原始压缩数据。

答案 2 :(得分: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。