压缩和解压源数据提供了比产生源数据的不同 [英] compressing and decompressing source data gives result different than source data

查看:259
本文介绍了压缩和解压源数据提供了比产生源数据的不同的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在我的应用程序,我需要解压缩由DataContractSerializer的写入压缩流放气在另一个应用程序,编辑解压缩后的数据,并再次压缩它的数据。

In my app I need to Decompress data written by DataContractSerializer to compression Deflate Stream in another app, edit the decompressed data and Compress it again.

减压工作得很好,但不适合我所压缩的数据。

Decompression works fine, but not for data compressed by me.

现在的问题是,当我这样做:
的byte []结果= Compressor.Compress(Compressor.Decompress(sourceData));

The problem is that when I do this: byte[] result = Compressor.Compress(Compressor.Decompress(sourceData));

结果字节数组的长度大于sourceData阵列的不同。

the length of the result byte array is different than sourceData array.

例如:

    string source = "test value";
    byte[] oryg = Encoding.Default.GetBytes(source);

    byte[] comp = Compressor.Compress(oryg);
    byte[] result1 = Compressor.Decompress(comp);

    string result2 = Encoding.Default.GetString(res);

和这里result1.Length为0,结果2是当然

and here result1.Length is 0 and result2 is "" of course

下面是我的压缩机类的代码。

Here is the code of my Compressor class.

public static class Compressor
{
    public static byte[] Decompress(byte[] data)
    {
        byte[] result;

        using (MemoryStream baseStream = new MemoryStream(data))
        {
            using (DeflateStream stream = new DeflateStream(baseStream, CompressionMode.Decompress))
            {
                result = ReadFully(stream, -1);
            }
        }

        return result;
    }

    public static byte[] Compress(byte[] data)
    {
        byte[] result;

        using (MemoryStream baseStream = new MemoryStream())
        {
            using (DeflateStream stream = new DeflateStream(baseStream, CompressionMode.Compress, true))
            {
                stream.Write(data, 0, data.Length);
                result = baseStream.ToArray();
            }
        }

        return result;
    }

    /// <summary>
    /// Reads data from a stream until the end is reached. The
    /// data is returned as a byte array. An IOException is
    /// thrown if any of the underlying IO calls fail.
    /// </summary>
    /// <param name="stream">The stream to read data from</param>
    /// <param name="initialLength">The initial buffer length</param>
    private static byte[] ReadFully(Stream stream, int initialLength)
    {
        // If we've been passed an unhelpful initial length, just
        // use 32K.
        if (initialLength < 1)
        {
            initialLength = 65768 / 2;
        }

        byte[] buffer = new byte[initialLength];
        int read = 0;

        int chunk;
        while ((chunk = stream.Read(buffer, read, buffer.Length - read)) > 0)
        {
            read += chunk;

            // If we've reached the end of our buffer, check to see if there's
            // any more information
            if (read == buffer.Length)
            {
                int nextByte = stream.ReadByte();

                // End of stream? If so, we're done
                if (nextByte == -1)
                {
                    return buffer;
                }

                // Nope. Resize the buffer, put in the byte we've just
                // read, and continue
                byte[] newBuffer = new byte[buffer.Length * 2];
                Array.Copy(buffer, newBuffer, buffer.Length);
                newBuffer[read] = (byte)nextByte;
                buffer = newBuffer;
                read++;
            }
        }
        // Buffer is now too big. Shrink it.
        byte[] ret = new byte[read];
        Array.Copy(buffer, ret, read);
        return ret;
    }
}

请如果你能帮助我这个情况。
最好的问候,
亚当

Please help me with this case if You can. Best regards, Adam

推荐答案

(编辑:利用冲洗,仍然可能不冲水开关所有字节,到现在确保放气首先被设置,按照菲尔的答案在这里: HTTP: //stackoverflow.com/questions/2118904/zip-and-unzip-string-with-deflate

(edited: switched from using flush, which still might not flush out all bytes, to now ensuring deflate is disposed first, as per Phil's answer here: http://stackoverflow.com/questions/2118904/zip-and-unzip-string-with-deflate)

尝试从后备存储器读取之前,必须确保在压缩时放气流已完全刷新自己,让放气来完成压缩和写入最终字节。关闭放气蒸,或它的处置,将实现这一点。

Before attempting to read from backing store, you have to ensure the deflate stream has fully flushed itself when compressing, allowing deflate to finish compressing and write final bytes. Closing the deflate steam, or disposing of it, will achieve this.

public static byte[] Compress(byte[] data)
{
    byte[] result;

    using (MemoryStream baseStream = new MemoryStream())
    {
        using (DeflateStream stream = new DeflateStream(baseStream, CompressionMode.Compress, true))
        {
            stream.Write(data, 0, data.Length);
        }
        result = baseStream.ToArray();  // only safe to read after deflate closed
    }

    return result;
}    



此外,您的日常的readFully难以置信看起来复杂,可能有错误。
之一是:

Also your ReadFully routine looks incredibly complicated and likely to have bugs. One being:

while ((chunk = stream.Read(buffer, read, buffer.Length - read)) > 0)

在读第二块,将超过缓冲区的长度时,这意味着它永远传递一个负值stream.Read对要读取的字节数。我的猜测是,它永远不会读第二块,返回零,并掉出while循环

When reading the 2nd chunk, read will be greater than the length of the buffer, meaning it'll always pass a negative value to stream.Read for the number of bytes to read. My guess is that it'll never read the 2nd chunk, returning zero, and fall out of the while loop.

我建议乔恩的版本的readFully用于此目的:
http://stackoverflow.com/questions/221925/creating-a - 字节数组从-A-流

I recommend Jon's version of ReadFully for this purpose: http://stackoverflow.com/questions/221925/creating-a-byte-array-from-a-stream

这篇关于压缩和解压源数据提供了比产生源数据的不同的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆