【C#基础知识-原生态压缩解压】文章转载自----->Warren专栏
下面为大家介绍一.NET下辅助公共类GZipHelper,该工具类主要作用是对文本、字符、文件等进行压缩与解压。该类主要使用命名空间:System.IO.Compression下的GZipStream类来实现。 此类表示 GZip 数据格式,它使用无损压缩和解压缩文件的行业标准算法。这种格式包括一个检测数据损坏的循环冗余校验值。GZip 数据格式使用的算法与 DeflateStream 类的算法相同,但它可以扩展以使用其他压缩格式。这种格式可以通过不涉及专利使用权的方式轻松实现。gzip 的格式可以从 RFC 1952“GZIP file format specification 4.3(GZIP 文件格式规范 4.3)GZIP file format specification 4.3(GZIP 文件格式规范 4.3)”中获得。此类不能用于压缩大于 4 GB 的文件。
一、属性
BaseStream 获取对基础流的引用。
CanRead 获取一个值,该值指示流是否支持在解压缩文件的过程中读取文件。 (重写 Stream..::.CanRead。)
CanSeek 获取一个值,该值指示流是否支持查找。 (重写 Stream..::.CanSeek。)
CanTimeout 获取一个值,该值确定当前流是否可以超时。 (继承自 Stream。)
CanWrite 获取一个值,该值指示流是否支持写入。 (重写 Stream..::.CanWrite。)
Length 不支持,并且总是引发 NotSupportedException。 (重写 Stream..::.Length。)
Position 不支持,并且总是引发 NotSupportedException。 (重写 Stream..::.Position。)
ReadTimeout 获取或设置一个值(以毫秒为单位),该值确定流在超时前尝试读取多长时间。 (继承自 Stream。)
WriteTimeout 获取或设置一个值(以毫秒为单位),该值确定流在超时前尝试写入多长时间。 (继承自 Stream。)
二、方法
BeginRead 开始异步读操作。 (重写 Stream..::.BeginRead(array<Byte>[]()[], Int32, Int32, AsyncCallback, Object)。)
BeginWrite 开始异步写操作。 (重写 Stream..::.BeginWrite(array<Byte>[]()[], Int32, Int32, AsyncCallback, Object)。)
Close 关闭当前流并释放与之关联的所有资源(如套接字和文件句柄)。 (继承自 Stream。)
CreateObjRef 创建一个对象,该对象包含生成用于与远程对象进行通信的代理所需的全部相关信息。 (继承自 MarshalByRefObject。)
Dispose 已重载。
EndRead 等待挂起的异步读取完成。 (重写 Stream..::.EndRead(IAsyncResult)。)
EndWrite 处理异步写入的结束。 (重写 Stream..::.EndWrite(IAsyncResult)。)
Flush 将当前 GZipStream 对象的内部缓冲区的内容刷新到基础流。 (重写 Stream..::.Flush()()()。)
GetHashCode 用作特定类型的哈希函数。 (继承自 Object。)
GetLifetimeService 检索控制此实例的生存期策略的当前生存期服务对象。 (继承自 MarshalByRefObject。)
InitializeLifetimeService 获取控制此实例的生存期策略的生存期服务对象。 (继承自 MarshalByRefObject。)
MemberwiseClone 已重载。
Read 将若干解压缩的字节读入指定的字节数组。 (重写 Stream..::.Read(array<Byte>[]()[], Int32, Int32)。)
ReadByte 从流中读取一个字节,并将流内的位置向前推进一个字节,或者如果已到达流的末尾,则返回 -1。 (继承自 Stream。)
Seek 此属性不受支持,并且总是引发 NotSupportedException。 (重写 Stream..::.Seek(Int64, SeekOrigin)。)
SetLength 此属性不受支持,并且总是引发 NotSupportedException。 (重写 Stream..::.SetLength(Int64)。)
Write 从指定的字节数组中将压缩的字节写入基础流。 (重写 Stream..::.Write(array<Byte>[]()[], Int32, Int32)。)
WriteByte 将一个字节写入流内的当前位置,并将流内的位置向前推进一个字节。 (继承自 Stream。)
使用原生的方法进行压缩解压文件实例代码:
/// <summary> /// 压缩文件 /// </summary> /// <param name="fileName">文件名(全路径)</param> /// <param name="data">需要压缩的字符串</param> public void CompressFile(string fileName, string data) { FileStream fstream = new FileStream(fileName, FileMode.Create, FileAccess.Write); GZipStream gstream = new GZipStream(fstream, CompressionMode.Compress); StreamWriter swriter = new StreamWriter(gstream); swriter.Write(data); swriter.Close(); gstream.Close(); fstream.Close(); }<br> /// <summary> /// 解压缩 /// </summary> /// <param name="fileName">文件名(全路径)</param> /// <returns></returns> public string DecompressFile(string fileName) { string cstring=""; FileStream fstream = new FileStream(fileName, FileMode.Open, FileAccess.Read); GZipStream gstream = new GZipStream(fstream, CompressionMode.Decompress); StreamReader reader = new StreamReader(gstream); cstring=reader.ReadToEnd(); reader.Close(); gstream.Close(); fstream.Close(); return cstring; }
GZipHelper公共类就是以GZipStream类为基础做的对常用解压缩进行的封装。GZipHelper类图如下所示:
using System; using System.IO; using System.IO.Compression; using System.Text; namespace RDIFramework.Utilities { /// <summary> /// 压缩文本、字节或者文件的压缩辅助类 /// </summary> public class GZipHelper { /// <summary> /// 压缩字符串 /// </summary> /// <param name="text"></param> /// <returns></returns> public static string Compress(string text) { // convert text to bytes byte[] buffer = Encoding.UTF8.GetBytes(text); // get a stream MemoryStream ms = new MemoryStream(); // get ready to zip up our stream using (GZipStream zip = new GZipStream(ms, CompressionMode.Compress, true)) { // compress the data into our buffer zip.Write(buffer, 0, buffer.Length); } // reset our position in compressed stream to the start ms.Position = 0; // get the compressed data byte[] compressed = ms.ToArray(); ms.Read(compressed, 0, compressed.Length); // prepare final data with header that indicates length byte[] gzBuffer = new byte[compressed.Length + 4]; //copy compressed data 4 bytes from start of final header System.Buffer.BlockCopy(compressed, 0, gzBuffer, 4, compressed.Length); // copy header to first 4 bytes System.Buffer.BlockCopy(BitConverter.GetBytes(buffer.Length), 0, gzBuffer, 0, 4); // convert back to string and return return Convert.ToBase64String(gzBuffer); } /// <summary> /// 解压字符串 /// </summary> /// <param name="compressedText"></param> /// <returns></returns> public static string Uncompress(string compressedText) { // get string as bytes byte[] gzBuffer = Convert.FromBase64String(compressedText); // prepare stream to do uncompression MemoryStream ms = new MemoryStream(); // get the length of compressed data int msgLength = BitConverter.ToInt32(gzBuffer, 0); // uncompress everything besides the header ms.Write(gzBuffer, 4, gzBuffer.Length - 4); // prepare final buffer for just uncompressed data byte[] buffer = new byte[msgLength]; // reset our position in stream since we're starting over ms.Position = 0; // unzip the data through stream GZipStream zip = new GZipStream(ms, CompressionMode.Decompress); // do the unzip zip.Read(buffer, 0, buffer.Length); // convert back to string and return return Encoding.UTF8.GetString(buffer); } public static T GZip<T>(Stream stream, CompressionMode mode) where T : Stream { byte[] writeData = new byte[4096]; T ms = default(T); using (Stream sg = new GZipStream(stream, mode)) { while (true) { Array.Clear(writeData, 0, writeData.Length); int size = sg.Read(writeData, 0, writeData.Length); if (size > 0) { ms.Write(writeData, 0, size); } else { break; } } return ms; } } /// <summary> /// 压缩字节 /// </summary> /// <param name="bytData"></param> /// <returns></returns> public static byte[] Compress(byte[] bytData) { using (MemoryStream stream = GZip<MemoryStream>(new MemoryStream(bytData), CompressionMode.Compress)) { return stream.ToArray(); } } /// <summary> /// 解压字节 /// </summary> /// <param name="bytData"></param> /// <returns></returns> public static byte[] Decompress(byte[] bytData) { using (MemoryStream stream = GZip<MemoryStream>(new MemoryStream(bytData), CompressionMode.Decompress)) { return stream.ToArray(); } } /// <summary> /// 压缩文件 /// </summary> /// <param name="sourceFile">源文件</param> /// <param name="destinationFile">目标文件</param> public static void CompressFile(string sourceFile, string destinationFile) { if (File.Exists(sourceFile) == false) //判断文件是否存在 throw new FileNotFoundException(); if (File.Exists(destinationFile) == false) //判断目标文件文件是否存在 FileHelper.FileDel(destinationFile); //创建文件流和字节数组 byte[] buffer = null; FileStream sourceStream = null; FileStream destinationStream = null; GZipStream compressedStream = null; try { sourceStream = new FileStream(sourceFile, FileMode.Open, FileAccess.Read, FileShare.Read); buffer = new byte[sourceStream.Length]; //把文件流存放到字节数组中 int checkCounter = sourceStream.Read(buffer, 0, buffer.Length); if (checkCounter != buffer.Length) { throw new ApplicationException(); } destinationStream = new FileStream(destinationFile, FileMode.OpenOrCreate, FileAccess.Write); //创建GzipStream实例,写入压缩的文件流 compressedStream = new GZipStream(destinationStream, CompressionMode.Compress, true); compressedStream.Write(buffer, 0, buffer.Length); } finally { // Make sure we allways close all streams if (sourceStream != null) { sourceStream.Close(); } if (compressedStream != null) { compressedStream.Close(); } if (destinationStream != null) { destinationStream.Close(); } } } /// <summary> /// 解压文件 /// </summary> /// <param name="sourceFile">源文件</param> /// <param name="destinationFile">目标文件</param> public static void DecompressFile(string sourceFile, string destinationFile) { if (!File.Exists(sourceFile)) { throw new FileNotFoundException(); } FileStream stream = null; FileStream stream2 = null; GZipStream stream3 = null; byte[] buffer = null; try { stream = new FileStream(sourceFile, FileMode.Open); stream3 = new GZipStream(stream, CompressionMode.Decompress, true); buffer = new byte[4]; int num = ((int)stream.Length) - 4; stream.Position = num; stream.Read(buffer, 0, 4); stream.Position = 0L; byte[] buffer2 = new byte[BitConverter.ToInt32(buffer, 0) + 100]; int offset = 0; int count = 0; while (true) { int num5 = stream3.Read(buffer2, offset, 100); if (num5 == 0) { break; } offset += num5; count += num5; } stream2 = new FileStream(destinationFile, FileMode.Create); stream2.Write(buffer2, 0, count); stream2.Flush(); } finally { if (stream != null) { stream.Close(); } if (stream3 != null) { stream3.Close(); } if (stream2 != null) { stream2.Close(); } } } } }
using
System;
using
System.IO;
using
System.IO.Compression;
using
System.Text;
namespace
RDIFramework.Utilities
{
/// <summary>
/// 压缩文本、字节或者文件的压缩辅助类
/// </summary>
public
class
GZipHelper
{
/// <summary>
/// 压缩字符串
/// </summary>
/// <param name="text"></param>
/// <returns></returns>
public
static
string
Compress(
string
text)
{
// convert text to bytes
byte
[] buffer = Encoding.UTF8.GetBytes(text);
// get a stream
MemoryStream ms =
new
MemoryStream();
// get ready to zip up our stream
using
(GZipStream zip =
new
GZipStream(ms, CompressionMode.Compress,
true
))
{
// compress the data into our buffer
zip.Write(buffer, 0, buffer.Length);
}
// reset our position in compressed stream to the start
ms.Position = 0;
// get the compressed data
byte
[] compressed = ms.ToArray();
ms.Read(compressed, 0, compressed.Length);
// prepare final data with header that indicates length
byte
[] gzBuffer =
new
byte
[compressed.Length + 4];
//copy compressed data 4 bytes from start of final header
System.Buffer.BlockCopy(compressed, 0, gzBuffer, 4, compressed.Length);
// copy header to first 4 bytes
System.Buffer.BlockCopy(BitConverter.GetBytes(buffer.Length), 0, gzBuffer, 0, 4);
// convert back to string and return
return
Convert.ToBase64String(gzBuffer);
}
/// <summary>
/// 解压字符串
/// </summary>
/// <param name="compressedText"></param>
/// <returns></returns>
public
static
string
Uncompress(
string
compressedText)
{
// get string as bytes
byte
[] gzBuffer = Convert.FromBase64String(compressedText);
// prepare stream to do uncompression
MemoryStream ms =
new
MemoryStream();
// get the length of compressed data
int
msgLength = BitConverter.ToInt32(gzBuffer, 0);
// uncompress everything besides the header
ms.Write(gzBuffer, 4, gzBuffer.Length - 4);
// prepare final buffer for just uncompressed data
byte
[] buffer =
new
byte
[msgLength];
// reset our position in stream since we're starting over
ms.Position = 0;
// unzip the data through stream
GZipStream zip =
new
GZipStream(ms, CompressionMode.Decompress);
// do the unzip
zip.Read(buffer, 0, buffer.Length);
// convert back to string and return
return
Encoding.UTF8.GetString(buffer);
}
public
static
T GZip<T>(Stream stream, CompressionMode mode)
where
T : Stream
{
byte
[] writeData =
new
byte
[4096];
T ms =
default
(T);
using
(Stream sg =
new
GZipStream(stream, mode))
{
while
(
true
)
{
Array.Clear(writeData, 0, writeData.Length);
int
size = sg.Read(writeData, 0, writeData.Length);
if
(size > 0)
{
ms.Write(writeData, 0, size);
}
else
{
break
;
}
}
return
ms;
}
}
/// <summary>
/// 压缩字节
/// </summary>
/// <param name="bytData"></param>
/// <returns></returns>
public
static
byte
[] Compress(
byte
[] bytData)
{
using
(MemoryStream stream = GZip<MemoryStream>(
new
MemoryStream(bytData), CompressionMode.Compress))
{
return
stream.ToArray();
}
}
/// <summary>
/// 解压字节
/// </summary>
/// <param name="bytData"></param>
/// <returns></returns>
public
static
byte
[] Decompress(
byte
[] bytData)
{
using
(MemoryStream stream = GZip<MemoryStream>(
new
MemoryStream(bytData), CompressionMode.Decompress))
{
return
stream.ToArray();
}
}
/// <summary>
/// 压缩文件
/// </summary>
/// <param name="sourceFile">源文件</param>
/// <param name="destinationFile">目标文件</param>
public
static
void
CompressFile(
string
sourceFile,
string
destinationFile)
{
if
(File.Exists(sourceFile) ==
false
)
//判断文件是否存在
throw
new
FileNotFoundException();
if
(File.Exists(destinationFile) ==
false
)
//判断目标文件文件是否存在
FileHelper.FileDel(destinationFile);
//创建文件流和字节数组
byte
[] buffer =
null
;
FileStream sourceStream =
null
;
FileStream destinationStream =
null
;
GZipStream compressedStream =
null
;
try
{
sourceStream =
new
FileStream(sourceFile, FileMode.Open, FileAccess.Read, FileShare.Read);
buffer =
new
byte
[sourceStream.Length];
//把文件流存放到字节数组中
int
checkCounter = sourceStream.Read(buffer, 0, buffer.Length);
if
(checkCounter != buffer.Length)
{
throw
new
ApplicationException();
}
destinationStream =
new
FileStream(destinationFile, FileMode.OpenOrCreate, FileAccess.Write);
//创建GzipStream实例,写入压缩的文件流
compressedStream =
new
GZipStream(destinationStream, CompressionMode.Compress,
true
);
compressedStream.Write(buffer, 0, buffer.Length);
}
finally
{
// Make sure we allways close all streams
if
(sourceStream !=
null
)
{ sourceStream.Close(); }
if
(compressedStream !=
null
)
{ compressedStream.Close(); }
if
(destinationStream !=
null
)
{ destinationStream.Close(); }
}
}
/// <summary>
/// 解压文件
/// </summary>
/// <param name="sourceFile">源文件</param>
/// <param name="destinationFile">目标文件</param>
public
static
void
DecompressFile(
string
sourceFile,
string
destinationFile)
{
if
(!File.Exists(sourceFile))
{
throw
new
FileNotFoundException();
}
FileStream stream =
null
;
FileStream stream2 =
null
;
GZipStream stream3 =
null
;
byte
[] buffer =
null
;
try
{
stream =
new
FileStream(sourceFile, FileMode.Open);
stream3 =
new
GZipStream(stream, CompressionMode.Decompress,
true
);
buffer =
new
byte
[4];
int
num = ((
int
)stream.Length) - 4;
stream.Position = num;
stream.Read(buffer, 0, 4);
stream.Position = 0L;
byte
[] buffer2 =
new
byte
[BitConverter.ToInt32(buffer, 0) + 100];
int
offset = 0;
int
count = 0;
while
(
true
)
{
int
num5 = stream3.Read(buffer2, offset, 100);
if
(num5 == 0)
{
break
;
}
offset += num5;
count += num5;
}
stream2 =
new
FileStream(destinationFile, FileMode.Create);
stream2.Write(buffer2, 0, count);
stream2.Flush();
}
finally
{
if
(stream !=
null
)
{
stream.Close();
}
if
(stream3 !=
null
)
{
stream3.Close();
}
if
(stream2 !=
null
)
{
stream2.Close();
}
}
}
}
}