C# SharpZipLib压缩字符串

C# SharpZipLib压缩字符串,c#,sharpziplib,C#,Sharpziplib,我需要压缩字符串以减小web服务响应的大小。我在SharpZipLib示例中看到了单元测试,但并不是我所需要的示例 在下面的代码中,ZipOutputStream的构造函数返回异常:“No open entry” 我在哪里偏离了轨道?我是否让它变得比应该的更复杂?在写入数据之前,需要调用putnextery来添加标题 答案复制自:在写入数据之前,您需要调用Putnextry来添加标题 答案复制自:您确定将数据转换为Base 64后,数据会更小吗?这将大大增加二进制数据(zip)。您不能使用HTT

我需要压缩字符串以减小web服务响应的大小。我在SharpZipLib示例中看到了单元测试,但并不是我所需要的示例

在下面的代码中,ZipOutputStream的构造函数返回异常:“No open entry”


我在哪里偏离了轨道?我是否让它变得比应该的更复杂?

在写入数据之前,需要调用putnextery来添加标题


答案复制自:

在写入数据之前,您需要调用Putnextry来添加标题


答案复制自:

您确定将数据转换为Base 64后,数据会更小吗?这将大大增加二进制数据(zip)。您不能使用HTTP压缩在传输级别解决这个问题吗

这里有一篇完整源代码的帖子,展示了如何进行双向压缩/解压缩


您确定将数据转换为Base 64后,数据会更小吗?这将大大增加二进制数据(zip)。您不能使用HTTP压缩在传输级别解决这个问题吗

这里有一篇完整源代码的帖子,展示了如何进行双向压缩/解压缩


您的代码有几个问题:

  • 使用流时始终刷新数据

  • 要从MemoryStream读取数据,只需使用:

    字节[]数据=ms.ToArray()

  • Zip文件是可能包含多个条目(文件)、注释。。。在开始向其写入数据之前,可能需要调用PutNextEntry()来添加新条目

  • 如果您只需要压缩单个数据流(这是您的情况),那么您的最佳选择就是简单地使用deflate(或gzip)压缩,这意味着压缩单个数据流(实际上zip格式在内部使用gzip压缩其条目…) Net提供了两个非常方便的数据压缩类:gzip流和DeflateStream。可以找到一个好的样品


  • 代码中的一些问题:

  • 使用流时始终刷新数据

  • 要从MemoryStream读取数据,只需使用:

    字节[]数据=ms.ToArray()

  • Zip文件是可能包含多个条目(文件)、注释。。。在开始向其写入数据之前,可能需要调用PutNextEntry()来添加新条目

  • 如果您只需要压缩单个数据流(这是您的情况),那么您的最佳选择就是简单地使用deflate(或gzip)压缩,这意味着压缩单个数据流(实际上zip格式在内部使用gzip压缩其条目…) Net提供了两个非常方便的数据压缩类:gzip流和DeflateStream。可以找到一个好的样品


  • 对于Silverlight的web服务通信压缩数据,我使用以下代码段:

    private byte[] zipText(string text)
    {
        if (text == null)
            return null;
    
        using(Stream memOutput = new MemoryStream())
        {
            using (GZipOutputStream zipOut = new GZipOutputStream(memOutput))
            {
                using (StreamWriter writer = new StreamWriter(zipOut))
                {
                    writer.Write(text);
    
                    writer.Flush();
                    zipOut.Finish();
    
                    byte[] bytes = new byte[memOutput.Length];
                    memOutput.Seek(0, SeekOrigin.Begin);
                    memOutput.Read(bytes, 0, bytes.Length);
    
                    return bytes;
                }
            }
        }
    }
    
    private string unzipText(byte[] bytes)
    {
        if (bytes == null)
            return null;
    
        using(Stream memInput = new MemoryStream(bytes))
        using(GZipInputStream zipInput = new GZipInputStream(memInput))
        using(StreamReader reader = new StreamReader(zipInput))
        {
            string text = reader.ReadToEnd();
    
            return text;
        }
    }
    
  • 我使用GZip而不是Zip压缩
  • 预计文本将从类似的环境中读/写,所以我没有做任何额外的编码/解码
  • 我的例子是json数据的压缩。根据我的观察,在某些情况下,大约95Kb的文本数据被压缩到1.5Kb。因此,即使数据也将序列化到base 64中,无论如何,这都是很好的流量节约


    发布了我的答案,这可能会节省一些时间。

    对于Silverlight的web服务通信压缩数据,我使用以下代码片段:

    private byte[] zipText(string text)
    {
        if (text == null)
            return null;
    
        using(Stream memOutput = new MemoryStream())
        {
            using (GZipOutputStream zipOut = new GZipOutputStream(memOutput))
            {
                using (StreamWriter writer = new StreamWriter(zipOut))
                {
                    writer.Write(text);
    
                    writer.Flush();
                    zipOut.Finish();
    
                    byte[] bytes = new byte[memOutput.Length];
                    memOutput.Seek(0, SeekOrigin.Begin);
                    memOutput.Read(bytes, 0, bytes.Length);
    
                    return bytes;
                }
            }
        }
    }
    
    private string unzipText(byte[] bytes)
    {
        if (bytes == null)
            return null;
    
        using(Stream memInput = new MemoryStream(bytes))
        using(GZipInputStream zipInput = new GZipInputStream(memInput))
        using(StreamReader reader = new StreamReader(zipInput))
        {
            string text = reader.ReadToEnd();
    
            return text;
        }
    }
    
  • 我使用GZip而不是Zip压缩
  • 预计文本将从类似的环境中读/写,所以我没有做任何额外的编码/解码
  • 我的例子是json数据的压缩。根据我的观察,在某些情况下,大约95Kb的文本数据被压缩到1.5Kb。因此,即使数据也将序列化到base 64中,无论如何,这都是很好的流量节约


    发布了我的答案,这可能会为某些人节省一些时间。

    我找到的最简单的答案是在解压/压缩数据时处理字节,并使用设置大小的缓冲区将数据复制到流对象,该对象可以按您喜欢的方式使用:

        /// <summary>
        /// Unzips (inflates) zipped data.
        /// </summary>
        /// <param name="zippedData">The zipped data.</param>
        /// <returns>The inflated data.</returns>
        public Byte[] GUnzip(Byte[] zippedData)
        {
            using (MemoryStream unzippedData = new MemoryStream())
            {
                using (GZipInputStream zippedDataStream = new GZipInputStream(new MemoryStream(zippedData)))
                {
                    CopyStream(zippedDataStream, unzippedData);
                }
    
                return unzippedData.ToArray();
            }
        }
    
        /// <summary>
        /// zips data.
        /// </summary>
        /// <param name="unzippedData">The unzipped data.</param>
        /// <returns>The zipped data.</returns>
        public Byte[] GZip(Byte[] unzippedData)
        {
            using (MemoryStream zippedData = new MemoryStream())
            {
                using (GZipOutputStream unzippedDataStream = new GZipOutputStream(new MemoryStream(unzippedData)))
                {
                    CopyStream(unzippedDataStream, zippedData);
                }
    
                return zippedData.ToArray();
            }
        }
    
        /// <summary>
        /// Accepts an inStream, writes it to a buffer and goes out the outStream
        /// </summary>
        /// <param name="inStream">The input Stream</param>
        /// <param name="outStream">The output Stream</param>
        private static void CopyStream(Stream inStream, Stream outStream)
        {
            int nRead = 0;
            // Using a 2k buffer
            Byte[] theBuffer = new Byte[2048];
    
            while ((nRead = inStream.Read(theBuffer, 0, theBuffer.Length)) > 0)
            {
                outStream.Write(theBuffer, 0, nRead);
            }
        }
    
    //
    ///解压缩(充气)压缩数据。
    /// 
    ///压缩后的数据。
    ///夸大的数据。
    公共字节[]GUnzip(字节[]zippedData)
    {
    使用(MemoryStream unzippedData=new MemoryStream())
    {
    使用(gzip输入流zippedDataStream=new gzip输入流(new MemoryStream(zippedData)))
    {
    CopyStream(压缩数据流、解压缩数据);
    }
    返回unzippedData.ToArray();
    }
    }
    /// 
    ///压缩数据。
    /// 
    ///解压后的数据。
    ///压缩后的数据。
    公共字节[]GZip(字节[]解压数据)
    {
    使用(MemoryStream zippedData=new MemoryStream())
    {
    使用(GZipOutputStream unzippedDataStream=newgzipoutputstream(newmemoryStream(unzippedData)))
    {
    CopyStream(解压缩数据流、压缩数据);
    }
    返回zippedData.ToArray();
    }
    }
    /// 
    ///接受内流,将其写入缓冲区并退出外流
    /// 
    ///输入流
    ///输出流
    私有静态void复制流(流内流、流外流)
    {
    int nRead=0;
    //使用2k缓冲区
    字节[]缓冲区=新字节[2048];
    而((nRead=inStream.Read(theBuffer,0,theBuffer.Length))>0)
    {
    写(缓冲区,0,nRead);
    }
    }
    
    我找到的最简单的答案是在解压/压缩数据时处理字节,并使用一个设置大小的缓冲区将数据复制到一个可以随意使用的流对象:

        /// <summary>
        /// Unzips (inflates) zipped data.
        /// </summary>
        /// <param name="zippedData">The zipped data.</param>
        /// <returns>The inflated data.</returns>
        public Byte[] GUnzip(Byte[] zippedData)
        {
            using (MemoryStream unzippedData = new MemoryStream())
            {
                using (GZipInputStream zippedDataStream = new GZipInputStream(new MemoryStream(zippedData)))
                {
                    CopyStream(zippedDataStream, unzippedData);
                }
    
                return unzippedData.ToArray();
            }
        }
    
        /// <summary>
        /// zips data.
        /// </summary>
        /// <param name="unzippedData">The unzipped data.</param>
        /// <returns>The zipped data.</returns>
        public Byte[] GZip(Byte[] unzippedData)
        {
            using (MemoryStream zippedData = new MemoryStream())
            {
                using (GZipOutputStream unzippedDataStream = new GZipOutputStream(new MemoryStream(unzippedData)))
                {
                    CopyStream(unzippedDataStream, zippedData);
                }
    
                return zippedData.ToArray();
            }
        }
    
        /// <summary>
        /// Accepts an inStream, writes it to a buffer and goes out the outStream
        /// </summary>
        /// <param name="inStream">The input Stream</param>
        /// <param name="outStream">The output Stream</param>
        private static void CopyStream(Stream inStream, Stream outStream)
        {
            int nRead = 0;
            // Using a 2k buffer
            Byte[] theBuffer = new Byte[2048];
    
            while ((nRead = inStream.Read(theBuffer, 0, theBuffer.Length)) > 0)
            {
                outStream.Write(theBuffer, 0, nRead);
            }
        }
    
    //
    ///解压缩(充气)压缩数据。
    /// 
    ///压缩后的数据。
    ///夸大的数据。
    公共字节[]GUnzip(字节[]zippedData)
    {
    使用(MemoryStream unzippedData=new MemoryStream())
    {
    使用(gzip输入流)压缩数据