您的位置:首页 > 编程语言 > C#

压缩文本、字节或者文件的压缩辅助类-GZipHelper 欢迎收藏

2015-06-15 14:14 573 查看
压缩文本、字节或者文件的压缩辅助类-GZipHelper 欢迎收藏  下面为大家介绍一.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。) 使用原生的方法进行压缩解压文件实例代码:
[csharp] view plaincopy
/// <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();

}

/// <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类图如下所示:

GZipHelper公共类完整源码:
[csharp] view plaincopy
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();

}

}

}

}

}

  

参考资料

MSDN GZipStream 类介绍
作者: EricHu
出处:http://blog.rdiframework.net/
Email:406590790@qq.com
QQ交流:406590790
关于作者:高级工程师、信息系统项目管理师、DBA。专注于微软平台项目架构、管理和企业解决方案,多年项目开发与管理经验,曾多次组织并开发多个大型项目,在面向对象、面向服务以及数据库领域有一定的造诣。现主要从事基于 RDIFramework.NET 框架的技术开发、咨询工作,主要服务于金融、医疗卫生、铁路、电信、物流、物联网、制造、零售等行业。
如有问题或建议,请多多赐教!
本文版权归作者和CNBLOGS博客共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,如有问题,可以通过邮箱或QQ 联系我,非常感谢。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息