3

Edit: I really just need to know when a Deflater derived class decides to write header and footer data, and how to exploit those facts. I would really like to do the following:

  1. Prime the dictionary for a Deflater derived class with some bytes (I think I got this).

  2. Send some data to be compressed to the Deflater derived class (I think I got this).

  3. Output all of that compressed data (WITH NO HEADER OR FOOTER DATA) to wherever I want (Not sure how to do this, it would also be okay to have both header/footer, or just one, just as long as it was consistent).

  4. Reuse object by starting again at 1.

Original Q: I am using the Java DeflaterOutputStream to compress some data. I am also modifying this compressed data by modifying the headers and the footers. I would like to give some input to DeflaterOutputStream, and have it only output the compressed data part, not the header or footer of the gzip format. How might I do this?

So far, I have been trying to do something like this:

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

internalWriter here is an extension of DeflaterOutputStream. This outputs the compressed data with header and footer. However, on subsequent calls with the same object, it outputs compressed data and footer. I basically want only the compressed data, or perhaps the same thing to happen each time. Any ideas? A quick explanation of how compression streams use close,flush,finish, might help me out too, with a focus on when the header and footer are created and outputted.

And every time I use DeflaterOutputStream, I want it to output everything right away. That is why I did the finish right after the right as seen above...

jsjwooowooo
  • 147
  • 1
  • 2
  • 9

3 Answers3

4

You can see good examples in Java Almanac

--- EDIT ---

Let me try to help a little more. The book Java I/O by Elliote Rusty Harold is perhaps the best reference I have found. You can get it from OReilly Books. I will provide you with some quotes and examples from the book.

Deflating Data

The Deflater class contains methods to compress blocks of data. You can choose the compression format, the level of compression, and the compression strategy. Deflating data with the Deflater class requires nine steps:

  1. Construct a Deflater object.
  2. Choose the strategy (optional).
  3. Set the compression level (optional).
  4. Preset the dictionary (optional).
  5. Set the input.
  6. Deflate the data repeatedly until needsInput( ) returns true.
  7. If more input is available, go back to step 5 to provide additional input data. Otherwise, go to step 8.
  8. Finish the data.
  9. If there are more streams to be deflated, reset the deflater.

More often than not, you don’t use this class directly. Instead, you use a Deflater object indirectly through one of the compressing stream classes like DeflaterInputStream or DeflaterOutputStream. These classes provide more convenient programmer interfaces for stream-oriented compression than the raw Deflater methods.

Inflating Data

  1. Construct an Inflater object.
  2. Set the input with the compressed data to be inflated.
  3. Call needsDictionary( ) to determine if a preset dictionary is required.
  4. If needsDictionary( ) returns true, call getAdler( ) to get the Adler-32 checksum of the dictionary. Then invoke setDictionary( ) to set the dictionary data.
  5. Inflate the data repeatedly until inflate( ) returns 0.
  6. If needsInput( ) returns true, go back to step 2 to provide additional input data.
  7. The finished( ) method returns true.

Now, the book dedicates a whole chapter to compressing and decompressing data, and I do not think it possible to explain it all here. You'll have to do you part of task and if needed, come back with a narrower question.

Edwin Dalorzo
  • 76,803
  • 25
  • 144
  • 205
  • @jsjwooowooo You question is too broad to be answered. Still I have extended my answer to give you more information and to recommend you a very good reference where you can find how to nail this problem once for all. Good luck! – Edwin Dalorzo Oct 25 '12 at 01:00
  • Okay, consider my question to be the following: when will a Deflater derived class output a header and/or footer for the format of chosen data compression. – jsjwooowooo Oct 25 '12 at 01:47
3

See the deflater (sic) documentation. If nowrap is true, then there is no header or trailer generated -- just raw compressed data in the deflate format.

Community
  • 1
  • 1
Mark Adler
  • 101,978
  • 13
  • 118
  • 158
  • Dude, thanks so much! Didn't catch that in the API! Now to figure out what is the default compression level for standard gzip... – jsjwooowooo Oct 25 '12 at 03:47
1

It sounds like you want to have two streams, your destination stream and then your compressor stream that decorates the destination stream. Then you'll write your uncompressed data to the base stream and the compressed data to the decorator stream. Make sure that you flush before switching. Reading will be a similar procedure, but you'll need to know where the compressed data begins and ends in your stream.

Suppose the destination stream is a file, something like the following pseudo code...

    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);

I wonder if DeflaterOutputStream is really what you want though. Isn't that part of a zip file? If you're doing something custom, it seems like you'd just want to gzip it.

Gregory Kalabin
  • 1,760
  • 1
  • 19
  • 45
BillRobertson42
  • 12,602
  • 4
  • 40
  • 57
  • Hrmm, perhaps check out my edit. The idea is any compressed output has a header/footer in it as per the definition of the GZIP file format. I want to deal with those. The header/footer are not something I am adding, they are something required for the file to be later decompressed. – jsjwooowooo Oct 25 '12 at 01:54
  • GZIP doesn't really have much of a format. If want files that are compatible with the gzip, then just use the GZIPOutputStream. – BillRobertson42 Oct 25 '12 at 02:04
  • Hrmm, well, the problem is I do think there is a format: http://www.ietf.org/rfc/rfc1952.txt And I kind of have to exploit it for the work I am currently doing. – jsjwooowooo Oct 25 '12 at 02:08