【问题标题】:Unzipped data being padded with '\0' when using DotNetZip and MemoryStream使用 DotNetZip 和 MemoryStream 时用 '\0' 填充解压缩数据
【发布时间】:2012-12-19 15:55:33
【问题描述】:

我正在尝试压缩和解压缩内存中的数据(因此,我不能使用 FileSystem),并且在下面的示例中,当数据被解压缩时,它的末尾有一种填充('\0' 字符)我的原始数据。

我做错了什么?

    [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
    }

【问题讨论】:

  • MemoryStream 在后台使用字节数组(缓冲区),当要写入的数据不适合时,它将增加(即加倍)其大小。 readStream.GetBuffer(); 会给你整个缓冲区。

标签: c# stream zip dotnetzip


【解决方案1】:

来自MSDN

"请注意,缓冲区包含可能未使用的已分配字节。例如,如果将字符串“test”写入 MemoryStream 对象,则从 GetBuffer 返回的缓冲区长度为 256,而不是 4,其中 252 字节未使用. 只获取缓冲区中的数据,使用ToArray方法;

所以你实际上想改变这一行: zipped = stream.GetBuffer();

到线:zipped = stream.ToArray();

【讨论】:

  • 好的,我明白了。要修复它,我们需要将所有调用从GetBuffer 替换为ToArray。在此示例中,有 2 个调用将被替换。谢谢。
【解决方案2】:

我怀疑它来自“MemoryStream.GetBuffer()”

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

请注意,缓冲区包含可能未使用的已分配字节。例如,如果将字符串“test”写入 MemoryStream 对象,则从 GetBuffer 返回的缓冲区长度为 256,而不是 4,其中 252 个字节未使用。要仅获取缓冲区中的数据,请使用 ToArray 方法;但是,ToArray 会在内存中创建数据的副本。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-12-22
    相关资源
    最近更新 更多