Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Unzipped data being padded with '\0' when using DotNetZip and MemoryStream

I'm trying to zip and unzip data in memory (so, I cannot use FileSystem), and in my sample below when the data is unzipped it has a kind of padding ('\0' chars) at the end of my original data.

What am I doing wrong ?

    [Test]
    public void Zip_and_Unzip_from_memory_buffer() {
        byte[] originalData = Encoding.UTF8.GetBytes("My string");

        byte[] zipped;
        using (MemoryStream stream = new MemoryStream()) {
            using (ZipFile zip = new ZipFile()) {
                //zip.CompressionMethod = CompressionMethod.BZip2;
                //zip.CompressionLevel = Ionic.Zlib.CompressionLevel.BestSpeed;
                zip.AddEntry("data", originalData);
                zip.Save(stream);
                zipped = stream.GetBuffer();
            }
        }

        Assert.AreEqual(256, zipped.Length); // Just to show that the zip has 256 bytes which match with the length unzipped below

        byte[] unzippedData;
        using (MemoryStream mem = new MemoryStream(zipped)) {
            using (ZipFile unzip = ZipFile.Read(mem)) {
                //ZipEntry zipEntry = unzip.Entries.FirstOrDefault();
                ZipEntry zipEntry = unzip["data"];
                using (MemoryStream readStream = new MemoryStream()) {
                    zipEntry.Extract(readStream);
                    unzippedData = readStream.GetBuffer();
                }
            }
        }

        Assert.AreEqual(256, unzippedData.Length); // WHY my data has trailing '\0' chars like a padding to 256 module ?
        Assert.AreEqual(originalData.Length, unzippedData.Length); // FAIL ! The unzipped data has 256 bytes
        //Assert.AreEqual(originalData, unzippedData); // FAIL at index 9
    }
like image 495
Luciano Avatar asked Dec 19 '12 15:12

Luciano


2 Answers

From MSDN

"Note that the buffer contains allocated bytes which might be unused. For example, if the string "test" is written into the MemoryStream object, the length of the buffer returned from GetBuffer is 256, not 4, with 252 bytes unused. To obtain only the data in the buffer, use the ToArray method;

So you actually want to change the line: zipped = stream.GetBuffer();

To the line: zipped = stream.ToArray();

like image 171
Blachshma Avatar answered Sep 27 '22 18:09

Blachshma


I suspect it is from 'MemoryStream.GetBuffer()'

http://msdn.microsoft.com/en-us/library/system.io.memorystream.getbuffer.aspx

Note that the buffer contains allocated bytes which might be unused. For example, if the string "test" is written into the MemoryStream object, the length of the buffer returned from GetBuffer is 256, not 4, with 252 bytes unused. To obtain only the data in the buffer, use the ToArray method; however, ToArray creates a copy of the data in memory.

like image 27
Jason Whitted Avatar answered Sep 27 '22 20:09

Jason Whitted