11using System . Buffers ;
2+ using GameFrameX . Foundation . Logger ;
23using ICSharpCode . SharpZipLib . GZip ;
4+ using ICSharpCode . SharpZipLib . Zip . Compression ;
35
46namespace GameFrameX . Utility ;
57
@@ -9,10 +11,15 @@ namespace GameFrameX.Utility;
911public static class CompressionHelper
1012{
1113 /// <summary>
12- /// 压缩数据。使用GZip算法将原始字节数组压缩成更小的字节数组。
14+ /// 用于压缩和解压缩操作的缓冲区大小(以字节为单位)
15+ /// </summary>
16+ private const int BufferSize = 8192 ;
17+
18+ /// <summary>
19+ /// 压缩数据。使用Deflate算法将原始字节数组压缩成更小的字节数组。
1320 /// </summary>
1421 /// <param name="bytes">要压缩的原始字节数组。不能为null。</param>
15- /// <returns>压缩后的字节数组。如果输入为空数组,则直接返回该空数组。</returns>
22+ /// <returns>压缩后的字节数组。如果输入为空数组,则直接返回该空数组。如果压缩过程中发生异常,则返回原始数组。 </returns>
1623 /// <exception cref="ArgumentNullException">当输入参数bytes为null时抛出。</exception>
1724 public static byte [ ] Compress ( byte [ ] bytes )
1825 {
@@ -22,22 +29,41 @@ public static byte[] Compress(byte[] bytes)
2229 return bytes ;
2330 }
2431
25- using ( var compressStream = new MemoryStream ( ) )
32+ var compressor = new Deflater ( ) ;
33+ compressor . SetLevel ( Deflater . BEST_COMPRESSION ) ;
34+
35+ compressor . SetInput ( bytes ) ;
36+ compressor . Finish ( ) ;
37+
38+ using var compressorMemoryStream = new MemoryStream ( bytes . Length ) ;
39+ var buffer = ArrayPool < byte > . Shared . Rent ( BufferSize ) ;
40+ try
2641 {
27- using ( var gZipOutputStream = new GZipOutputStream ( compressStream ) )
42+ while ( ! compressor . IsFinished )
2843 {
29- gZipOutputStream . Write ( bytes , 0 , bytes . Length ) ;
30- var press = compressStream . ToArray ( ) ;
31- return press ;
44+ var count = compressor . Deflate ( buffer ) ;
45+ compressorMemoryStream . Write ( buffer , 0 , count ) ;
3246 }
47+
48+ return compressorMemoryStream . ToArray ( ) ;
49+ }
50+ catch ( Exception e )
51+ {
52+ LogHelper . Fatal ( e ) ;
53+ }
54+ finally
55+ {
56+ ArrayPool < byte > . Shared . Return ( buffer ) ;
3357 }
58+
59+ return bytes ;
3460 }
3561
3662 /// <summary>
37- /// 解压数据。使用GZip算法将压缩的字节数组还原成原始字节数组 。
63+ /// 解压数据。使用Inflate算法将压缩的字节数组还原成原始字节数组 。
3864 /// </summary>
3965 /// <param name="bytes">要解压的压缩字节数组。不能为null。</param>
40- /// <returns>解压后的原始字节数组。如果输入为空数组,则直接返回该空数组。</returns>
66+ /// <returns>解压后的原始字节数组。如果输入为空数组,则直接返回该空数组。如果解压过程中发生异常,则返回原始数组。 </returns>
4167 /// <exception cref="ArgumentNullException">当输入参数bytes为null时抛出。</exception>
4268 /// <exception cref="InvalidDataException">当压缩数据格式无效或已损坏时抛出。</exception>
4369 public static byte [ ] Decompress ( byte [ ] bytes )
@@ -48,30 +74,29 @@ public static byte[] Decompress(byte[] bytes)
4874 return bytes ;
4975 }
5076
51- using ( var compressedStream = new MemoryStream ( bytes ) )
77+ var decompressor = new Inflater ( ) ;
78+ decompressor . SetInput ( bytes , 0 , bytes . Length ) ;
79+ using var decompressMemoryStream = new MemoryStream ( bytes . Length ) ;
80+ var buffer = ArrayPool < byte > . Shared . Rent ( BufferSize ) ;
81+ try
5282 {
53- using ( var gZipInputStream = new GZipInputStream ( compressedStream ) )
83+ while ( ! decompressor . IsFinished )
5484 {
55- using ( var decompressedStream = new MemoryStream ( ) )
56- {
57- var buffer = ArrayPool < byte > . Shared . Rent ( 8192 ) ;
58- try
59- {
60- int count ;
61- while ( ( count = gZipInputStream . Read ( buffer , 0 , buffer . Length ) ) != 0 )
62- {
63- decompressedStream . Write ( buffer , 0 , count ) ;
64- }
65- }
66- finally
67- {
68- ArrayPool < byte > . Shared . Return ( buffer ) ;
69- }
70-
71- var array = decompressedStream . ToArray ( ) ;
72- return array ;
73- }
85+ var count = decompressor . Inflate ( buffer ) ;
86+ decompressMemoryStream . Write ( buffer , 0 , count ) ;
7487 }
88+
89+ return decompressMemoryStream . ToArray ( ) ;
7590 }
91+ catch ( Exception e )
92+ {
93+ LogHelper . Fatal ( e ) ;
94+ }
95+ finally
96+ {
97+ ArrayPool < byte > . Shared . Return ( buffer , true ) ;
98+ }
99+
100+ return bytes ;
76101 }
77102}
0 commit comments