下面为大家介绍一.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。)
使用原生的方法进行压缩解压文件实例代码:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
|
/// <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类图如下所示:
GZipHelper公共类完整源码:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
|
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();
}
}
}
}
}
|