Question

I need a zlib deflate compressed stream. In my implementation I must use a single stream over the entire session. during this session small chunks of data will be passed through the compressed stream. Everytime a chunk is passed it must be sent in compressed form immediately.

My first attempt was using DeflateStream but when I send the first chunk its compressed data wont appear until I close the stream.

Reading about zlib flush modes it appears as if there is one specific mode for what I need.

  1. Am I using the correct class(DeflateStream) for zlib deflate compression?
  2. How can I enable "sync flush" behavior?
Was it helpful?

Solution

The DotNetZip project has a submodule Zlib that contain an implementation of DeflateStream of its own.

This implementation has another property named FlushMode:

DeflateStream deflate = new DeflateStream(stream, CompressionMode.Compress);
deflate.FlushMode = FlushType.Sync;
deflate.Write (data, 0, data.Length);
//No call to deflate.Flush() needed, automatically flushed on every write.

OTHER TIPS

It does indeed only flush upon close. You will need to use a different DeflateStream instance each time, passing true to the overloaded constructor telling it not to close the underlying stream when you close the DeflateStream.

To answer your question about how you could enable "sync flush" behavior, you should see the zpipe.c example in the zlib source code.
Replace the 1st line with the 2nd line shown below

Deflate() will return each time the output buffer is full or when the input buffer is empty meanwhile appending to the compressed stream an empty literal block also called a "sync flush" except at the end which is the Z_FINISH flag.

    flush = feof(source) ? Z_FINISH : Z_NO_FLUSH;
    flush = feof(source) ? Z_FINISH : Z_SYNC_FLUSH;
    ret = deflate(&strm, flush);
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top