1.GZipStream 类
此类在 .NET Framework 2.0 版中是新增的。
提供用于压缩和解压缩流的方法和属性
2.压缩byte[]
/// <summary>
/// 压缩数据
/// </summary>
/// <param name="data"></param>
/// <returns></returns>
public byte[] Compress(byte[] data)
{
MemoryStream ms = new MemoryStream();
GZipStream zipStream = new GZipStream(ms, CompressionMode.Compress);
zipStream.Write(data, 0, data.Length);//将数据压缩并写到基础流中
zipStream.Close();
return ms.ToArray();
}
3.解压byte[]
/// 解压数据
/// </summary>
/// <param name="data"></param>
/// <returns></returns>
public byte[] Decompress(byte[] data)
{
MemoryStream srcMs = new MemoryStream(data);
GZipStream zipStream = new GZipStream(srcMs, CompressionMode.Decompress);
MemoryStream ms = new MemoryStream();
byte[] bytes = new byte[40960];
int n;
while ((n = zipStream.Read(bytes, 0, bytes.Length)) > 0)
{
ms.Write(bytes, 0, n);
}
zipStream.Close();
return ms.ToArray();
}
4.压缩byte[]数据,存放到文件中
/// <summary>
/// 将指定的字节数组压缩,并写入到目标文件
/// </summary>
/// <param name="srcBuffer">指定的源字节数组</param>
/// <param name="destFile">指定的目标文件</param>
public static void CompressData(byte[] srcBuffer, string destFile)
{
FileStream destStream = null;
GZipStream compressedStream = null;
try
{
//打开文件流
destStream = new FileStream(destFile, FileMode.OpenOrCreate, FileAccess.Write);
//指定压缩的目的流(这里是文件流)
compressedStream = new GZipStream(destStream, CompressionMode.Compress, true);
//往目的流中写数据,而流将数据写到指定的文件
compressedStream.Write(srcBuffer, 0, srcBuffer.Length);
}
catch (Exception ex)
{
throw new Exception(String.Format("压缩数据写入文件{0}时发生错误", destFile), ex);
}
finally
{
// Make sure we allways close all streams
if (null != compressedStream)
{
compressedStream.Close();
compressedStream.Dispose();
}
if (null != destStream)
destStream.Close();
}
}
5.解压文件,得到byte[]数据
/// <summary>
/// 将指定的文件解压,返回解压后的数据
/// </summary>
/// <param name="srcFile">指定的源文件</param>
/// <returns>解压后得到的数据</returns>
public static byte[] DecompressData(string srcFile)
{
if (false == File.Exists(srcFile))
throw new FileNotFoundException(String.Format("找不到指定的文件{0}", srcFile));
FileStream sourceStream = null;
GZipStream decompressedStream = null;
byte[] quartetBuffer = null;
try
{
sourceStream = new FileStream(srcFile, FileMode.Open, FileAccess.Read, FileShare.Read);
decompressedStream = new GZipStream(sourceStream, CompressionMode.Decompress, true);
// Read the footer to determine the length of the destiantion file
//GZIP文件格式说明:
//10字节的头,包含幻数、版本号以及时间戳
//可选的扩展头,如原文件名
//文件体,包括DEFLATE压缩的数据
//8字节的尾注,包括CRC-32校验和以及未压缩的原始数据长度(4字节) 文件大小不超过4G
//为Data指定byte的长度,故意开大byte数据的范围
//读取未压缩的原始数据长度
quartetBuffer = new byte[4];
long position = sourceStream.Length - 4;
sourceStream.Position = position;
sourceStream.Read(quartetBuffer, 0, 4);
int checkLength = BitConverter.ToInt32(quartetBuffer, 0);
byte[] data;
if (checkLength <= sourceStream.Length)
{
data = new byte[Int16.MaxValue];
}
else
{
data = new byte[checkLength + 100];
}
//每100byte从解压流中读出数据,并将读出的数据Copy到Data byte[]中,这样就完成了对数据的解压
byte[] buffer = new byte[100];
sourceStream.Position = 0;
int offset = 0;
int total = 0;
while (true)
{
int bytesRead = decompressedStream.Read(buffer, 0, 100);
if (bytesRead == 0)
break;
buffer.CopyTo(data, offset);
offset += bytesRead;
total += bytesRead;
}
//剔除多余的byte
byte[] actualdata = new byte[total];
for (int i = 0; i < total; i++)
actualdata[i] = data[i];
return actualdata;
}
catch (Exception ex)
{
throw new Exception(String.Format("从文件{0}解压数据时发生错误", srcFile), ex);
}
finally
{
if (sourceStream != null)
sourceStream.Close();
if (decompressedStream != null)
decompressedStream.Close();
}
}
6.小结
压缩,解压都用GZipStream,操作的对象时普通流MemoryStream,不同的是:
压缩是将btye[]型的数据写入GZipStream中,而解压的时候是将GzipStream中的数据写入到byte[]中,并将读出的数据写入到MemoryStream后一次性输出
压缩到文件与压缩成byte[]不同的是压缩到文件利用到了FileStream将流写到文件,解压Gzip文件,需要根据文件的规则进行:后4位记录未压缩前的长度,根据该长度可以将解压出来的文件存放到稍大的
byte[]中
此类在 .NET Framework 2.0 版中是新增的。
提供用于压缩和解压缩流的方法和属性
2.压缩byte[]
/// <summary>
/// 压缩数据
/// </summary>
/// <param name="data"></param>
/// <returns></returns>
public byte[] Compress(byte[] data)
{
MemoryStream ms = new MemoryStream();
GZipStream zipStream = new GZipStream(ms, CompressionMode.Compress);
zipStream.Write(data, 0, data.Length);//将数据压缩并写到基础流中
zipStream.Close();
return ms.ToArray();
}
3.解压byte[]
/// 解压数据
/// </summary>
/// <param name="data"></param>
/// <returns></returns>
public byte[] Decompress(byte[] data)
{
MemoryStream srcMs = new MemoryStream(data);
GZipStream zipStream = new GZipStream(srcMs, CompressionMode.Decompress);
MemoryStream ms = new MemoryStream();
byte[] bytes = new byte[40960];
int n;
while ((n = zipStream.Read(bytes, 0, bytes.Length)) > 0)
{
ms.Write(bytes, 0, n);
}
zipStream.Close();
return ms.ToArray();
}
4.压缩byte[]数据,存放到文件中
/// <summary>
/// 将指定的字节数组压缩,并写入到目标文件
/// </summary>
/// <param name="srcBuffer">指定的源字节数组</param>
/// <param name="destFile">指定的目标文件</param>
public static void CompressData(byte[] srcBuffer, string destFile)
{
FileStream destStream = null;
GZipStream compressedStream = null;
try
{
//打开文件流
destStream = new FileStream(destFile, FileMode.OpenOrCreate, FileAccess.Write);
//指定压缩的目的流(这里是文件流)
compressedStream = new GZipStream(destStream, CompressionMode.Compress, true);
//往目的流中写数据,而流将数据写到指定的文件
compressedStream.Write(srcBuffer, 0, srcBuffer.Length);
}
catch (Exception ex)
{
throw new Exception(String.Format("压缩数据写入文件{0}时发生错误", destFile), ex);
}
finally
{
// Make sure we allways close all streams
if (null != compressedStream)
{
compressedStream.Close();
compressedStream.Dispose();
}
if (null != destStream)
destStream.Close();
}
}
5.解压文件,得到byte[]数据
/// <summary>
/// 将指定的文件解压,返回解压后的数据
/// </summary>
/// <param name="srcFile">指定的源文件</param>
/// <returns>解压后得到的数据</returns>
public static byte[] DecompressData(string srcFile)
{
if (false == File.Exists(srcFile))
throw new FileNotFoundException(String.Format("找不到指定的文件{0}", srcFile));
FileStream sourceStream = null;
GZipStream decompressedStream = null;
byte[] quartetBuffer = null;
try
{
sourceStream = new FileStream(srcFile, FileMode.Open, FileAccess.Read, FileShare.Read);
decompressedStream = new GZipStream(sourceStream, CompressionMode.Decompress, true);
// Read the footer to determine the length of the destiantion file
//GZIP文件格式说明:
//10字节的头,包含幻数、版本号以及时间戳
//可选的扩展头,如原文件名
//文件体,包括DEFLATE压缩的数据
//8字节的尾注,包括CRC-32校验和以及未压缩的原始数据长度(4字节) 文件大小不超过4G
//为Data指定byte的长度,故意开大byte数据的范围
//读取未压缩的原始数据长度
quartetBuffer = new byte[4];
long position = sourceStream.Length - 4;
sourceStream.Position = position;
sourceStream.Read(quartetBuffer, 0, 4);
int checkLength = BitConverter.ToInt32(quartetBuffer, 0);
byte[] data;
if (checkLength <= sourceStream.Length)
{
data = new byte[Int16.MaxValue];
}
else
{
data = new byte[checkLength + 100];
}
//每100byte从解压流中读出数据,并将读出的数据Copy到Data byte[]中,这样就完成了对数据的解压
byte[] buffer = new byte[100];
sourceStream.Position = 0;
int offset = 0;
int total = 0;
while (true)
{
int bytesRead = decompressedStream.Read(buffer, 0, 100);
if (bytesRead == 0)
break;
buffer.CopyTo(data, offset);
offset += bytesRead;
total += bytesRead;
}
//剔除多余的byte
byte[] actualdata = new byte[total];
for (int i = 0; i < total; i++)
actualdata[i] = data[i];
return actualdata;
}
catch (Exception ex)
{
throw new Exception(String.Format("从文件{0}解压数据时发生错误", srcFile), ex);
}
finally
{
if (sourceStream != null)
sourceStream.Close();
if (decompressedStream != null)
decompressedStream.Close();
}
}
6.小结
压缩,解压都用GZipStream,操作的对象时普通流MemoryStream,不同的是:
压缩是将btye[]型的数据写入GZipStream中,而解压的时候是将GzipStream中的数据写入到byte[]中,并将读出的数据写入到MemoryStream后一次性输出
压缩到文件与压缩成byte[]不同的是压缩到文件利用到了FileStream将流写到文件,解压Gzip文件,需要根据文件的规则进行:后4位记录未压缩前的长度,根据该长度可以将解压出来的文件存放到稍大的
byte[]中