写了两个方法,用.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
(一)压缩:
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
调用MSDN例子里的函数ReadAllBytesFromStream读也会发生同样的异常~!
但按照MSDN里的例子那样写就没问题,和MSDN例子的区别是我将压缩和解压分开成两个函数了。
没人知道为什么吗?
因为程序其它地方只用string,不用byte。
特别是,加密后的字符串准备传递给第三方程序接口进行存储,它的参数是string类型的
谢谢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);//转换为普通的字符串
}
{
MemoryStream ms = new MemoryStream();
DeflateStream cprs = new DeflateStream(ms, CompressionMode.Compress);
cprs.Write(bytes, 0, bytes.Length);
cprs.Close();
return ms.ToArray(); }