写了两个方法,用.net 自带的System.IO.Compression.DeflateStream类进行【字符串】的压缩和解压。
(一)压缩:
        public static string Compress(string strSource)
        {
            System.Text.Encoding encoding = System.Text.Encoding.Unicode;
            byte[] buffer = encoding.GetBytes(strSource);            System.IO.MemoryStream ms = new System.IO.MemoryStream();
            System.IO.Compression.DeflateStream stream = new System.IO.Compression.DeflateStream(ms, System.IO.Compression.CompressionMode.Compress, true);
            stream.Write(buffer, 0, buffer.Length);
            stream.Close();            buffer = ms.ToArray();
            ms.Close();            return encoding.GetString(buffer);
        }(二)解压:
        public static string Decompress(string strSource)
        {
            System.Text.Encoding encoding = System.Text.Encoding.Unicode;
            byte[] buffer = encoding.GetBytes(strSource);            System.IO.MemoryStream ms = new System.IO.MemoryStream();
            ms.Write(buffer, 0, buffer.Length);
            ms.Position = 0;
            System.IO.Compression.DeflateStream stream = new System.IO.Compression.DeflateStream(ms, System.IO.Compression.CompressionMode.Decompress);
            stream.Flush();            int nSize = 2 * 1024 * 1024;
            byte[] decompressBuffer = new byte[nSize];
            stream.Read(decompressBuffer, 0, nSize); //××××{{ 这里死活不能读,一读就出异常 }}××××
            //int nSizeRead = ReadAllBytesFromStream(stream, decompressBuffer);
            stream.Close();            return encoding.GetString(decompressBuffer);
        }从调试结果看,方法一(压缩字符串)执行结果正常。
但到了方法二(解压字符串),红色显示的那一行一定会出现如下异常:
2008-10-29 18:29:31  System.IndexOutOfRangeException: 索引超出了数组界限。
   在 System.IO.Compression.HuffmanTree.CreateTable()
   在 System.IO.Compression.HuffmanTree..ctor(Byte[] codeLengths)
   在 System.IO.Compression.Inflater.DecodeDynamicBlockHeader()
   在 System.IO.Compression.Inflater.Decode()
   在 System.IO.Compression.Inflater.Inflate(Byte[] bytes, Int32 offset, Int32 length)
   在 System.IO.Compression.DeflateStream.Read(Byte[] array, Int32 offset, Int32 count)
   在 {名字空间省略}.PlanManager.Decompress(String strSource) 位置 {路径省略...}\PlanManager.cs:行号 164

解决方案 »

  1.   

    //int nSizeRead = ReadAllBytesFromStream(stream, decompressBuffer); 
    调用MSDN例子里的函数ReadAllBytesFromStream读也会发生同样的异常~!
    但按照MSDN里的例子那样写就没问题,和MSDN例子的区别是我将压缩和解压分开成两个函数了。
    没人知道为什么吗?
      

  2.   

    为什么要转成String而不直接传byte[]?
      

  3.   


    因为程序其它地方只用string,不用byte。
    特别是,加密后的字符串准备传递给第三方程序接口进行存储,它的参数是string类型的
      

  4.   

    那也不能用Encoding,用Convert.ToBase64String
      

  5.   


    谢谢danjiewu,按照你的提示,问题解决了。
    字符串压缩后,将得到的byte[]数组用Convert.ToBase64String转换Base64String,解压时,传入这个Base64String,用Convert.FromBase64String转换为byte[],再按照原来的过程执行就不出那个异常了。比较压缩前和解压后的字符串,完全相同。附上代码如下,
    压缩:        public static string Compress(string strSource)
            {
                if (strSource == null || strSource.Length > 8 * 1024)
                    throw new System.ArgumentException("字符串为空或长度太大!");            System.Text.Encoding encoding = System.Text.Encoding.Unicode;
                byte[] buffer = encoding.GetBytes(strSource);
                //byte[] buffer = Convert.FromBase64String(strSource); //传入的字符串不一定是Base64String类型,这样写不行            System.IO.MemoryStream ms = new System.IO.MemoryStream();
                System.IO.Compression.DeflateStream stream = new System.IO.Compression.DeflateStream(ms, System.IO.Compression.CompressionMode.Compress, true);
                stream.Write(buffer, 0, buffer.Length);
                stream.Close();            buffer = ms.ToArray();
                ms.Close();            return Convert.ToBase64String(buffer); //将压缩后的byte[]转换为Base64String
            }
    解压:        public static string Decompress(string strSource)
            {
                //System.Text.Encoding encoding = System.Text.Encoding.Unicode;
                //byte[] buffer = encoding.GetBytes(strSource);
                byte[] buffer = Convert.FromBase64String(strSource);            System.IO.MemoryStream ms = new System.IO.MemoryStream();
                ms.Write(buffer, 0, buffer.Length);
                ms.Position = 0;
                System.IO.Compression.DeflateStream stream = new System.IO.Compression.DeflateStream(ms, System.IO.Compression.CompressionMode.Decompress);
                stream.Flush();            int nSize = 16 * 1024 + 256; //字符串不会超过16K
                byte[] decompressBuffer = new byte[nSize];
                int nSizeIncept = stream.Read(decompressBuffer, 0, nSize);
                stream.Close();            return System.Text.Encoding.Unicode.GetString(decompressBuffer, 0, nSizeIncept);//转换为普通的字符串
            }
      

  6.   

    我给你个例子,在我的项目里用的。这是压缩,解压道理完全一样的,自己翻一下。 public static byte[] Compress(byte[] bytes)
            {
                MemoryStream ms = new MemoryStream();
                DeflateStream cprs = new DeflateStream(ms, CompressionMode.Compress);
                cprs.Write(bytes, 0, bytes.Length);
                cprs.Close();        
                return ms.ToArray();        }