Aleksandrov Stas
Aleksandrov Stas

Reputation: 3

GZipStream corrupts file if i pack it in parts (Flush doesn't work)

I've tried to use this code to compress a file in parts

using (var fsIn = new FileStream("test.avi", FileMode.Open))
{
    using (var fsOut = new FileStream("test.avi.gz", FileMode.Create))
    {
        var buf = new byte[1024 * 1024];

        using (var gzip = new GZipStream(fsOut, CompressionMode.Compress, true))
        {
            while (true)
            {
                var readCount = fsIn.Read(buf, 0, buf.Length);
                if (readCount <= 0)
                {
                    break;
                }

                gzip.Write(buf, 0, buf.Length);
                gzip.Flush();
            }
        }
    }
}

but i've got corrupted file after decompression. This code works

using (var fsIn = new FileStream("test.avi", FileMode.Open))
{
    using (var fsOut = new FileStream("test.avi.gz", FileMode.Create))
    {
        var buf = new byte[1024*1024];

        while (true)
        {
            var readCount = fsIn.Read(buf, 0, buf.Length);
            if (readCount <= 0)
            {
                break;
            }

            // This string was transferred into "while" cycle
            using (var gzip = new GZipStream(fsOut, CompressionMode.Compress, true))
            {
                gzip.Write(buf, 0, buf.Length);
            }
        }
    }
}

Why gzip.Flush() doesn't work? Why only gzip.Close() works?

Upvotes: 0

Views: 975

Answers (3)

Lev  Alefirenko
Lev Alefirenko

Reputation: 93

File is compressed properly. in fact it turns out that the file contains a set of compressed files. Archives number equal to the number parts. At each new iteration, a new file and appended to the file. decision

You need to specify the length of the packaging after the packaging and before burning to file.

Just like that:

Compress:

BitConverter.GetBytes(compressedPart.Length).CopyTo(blockToWrite, 4);

In decompression read this length and choose part of the file is equal to this length for decompression.

Upvotes: 0

Mzf
Mzf

Reputation: 5260

Yuo need to know that gzip.Flush(); is not working

From MSDN - GZipStream.Flush :

The current implementation of this method does not flush the internal buffer. The internal buffer is flushed when the object is disposed.

Upvotes: 0

Ahmed KRAIEM
Ahmed KRAIEM

Reputation: 10427

new GZipStream(fsOut, CompressionMode.Compress, true) leaves the stream open after disposing, you should change the last parameter to false.

GZipStream Constructor (Stream, CompressionMode, Boolean)

leaveOpen
Type: System.Boolean
true to leave the stream open after disposing the GZipStream object; otherwise, false.

Also Flush() has no effects in GZipStream

The current implementation of this method does not flush the internal buffer. The internal buffer is flushed when the object is disposed.

Upvotes: 1

Related Questions