我正在使用GZIP来压缩ASCII字符串(base64(,但是,它会产生更多的数据而不是较少的数据。谁能帮忙?
这是一个旧项目,我仅限于编译器和框架版本。我尝试了MSBUILD 2.0、3.5&4.0-都产生相同的错误结果。
Imports System.IO.Compression
Private Function GZipString(ByVal asciiString As String) as Byte()
Debug.Print ("asciiString length : {0}", asciiString.Length )
Dim asciibytes As Byte() = Encoding.ASCII.GetBytes(asciiString)
Debug.Print ("asciibytes length : {0}", asciibytes.Length )
'GZip the string
Dim ms As New MemoryStream()
Dim gzips As New GZipStream(ms, CompressionMode.Compress)
gzips.Write(asciibytes, 0, asciibytes.Length)
gzips.Close()
GZipString = ms.ToArray
ms.Close()
Debug.Print ("compressedBytes length : {0}", GZipString.Length )
End Function
我获得的输出是: -
- 施法长度:3607
- asciibytes长度:3607
- 压缩长度:3985
1。(这是2019年,使用UTF8
,而不是ASCII
;UTF8
兼容99%,并在国际角色(汉字,表情符号,您可以输入的任何内容(的支持下提供了支持。大多数Web浏览器和服务器甚至默认为UTF8
编码格式(它们有多年(。通常应该避免使用ASCII
,除非您正在使用需要它的旧软件...(即使到那时,仅对于与该旧系统交谈的代码的一部分!(
2。(为参考,压缩字符串不会总是会导致字节更少;特别是小弦;虽然3600字符串应该压缩(除非它包含完全随机的垃圾,否则该长度的人类键入纯文本字符串绝对应该压缩(。
3。(您应该正确处理对象(通过using
语句(。不这样做会导致资源和/或内存泄漏。
4。(您的压缩或减压代码是错误的;GZipStream
可以是超级挑剔的;因此,我在下面包括了适用于C#
和VB.NET
的测试代码。
C#版本:
static void Main(string[] args)
{
var input = string.Join(" ", args);
var compressedBytes = CompressString(input);
var dec = DecompressString(compressedBytes);
Console.WriteLine("Input Length = " + input.Length); // 537
Console.WriteLine("Uncompressed Size = " + Encoding.UTF8.GetBytes(input).Length); // 539
Console.WriteLine("Compressed Size = " + compressedBytes.Length); // 354 (smaller!)
Console.WriteLine("Decompressed Length = " + dec.Length); // 537 (same size!)
Console.WriteLine("Roundtrip Successful: " + (input == dec)); // True
}
public static string DecompressString(byte[] bytes)
{
using (var ms = new MemoryStream(bytes))
using (var ds = new GZipStream(ms, CompressionMode.Decompress))
using (var sr = new StreamReader(ds))
{
return sr.ReadToEnd();
}
}
public static byte[] CompressString(string input)
{
using (var ms = new MemoryStream())
using (var cs = new GZipStream(ms, CompressionLevel.Optimal))
{
var bytes = Encoding.UTF8.GetBytes(input);
cs.Write(bytes, 0, bytes.Length);
// *REQUIRED* or last chunk will be omitted. Do NOT call any other close or
// flush method.
cs.Close();
return ms.ToArray();
}
}
vb.net版本
(总觉得肮脏😜(:
Sub Main(args As String())
Dim input As String = String.Join(" ", args)
Dim compressedBytes As Byte() = CompressString(input)
Dim dec As String = DecompressString(compressedBytes)
Console.WriteLine("Input Length = " & input.Length) ' 537
Console.WriteLine("Uncompressed Size = " & Encoding.UTF8.GetBytes(input).Length) ' 539
Console.WriteLine("Compressed Size = " & compressedBytes.Length) ' 354 (smaller!)
Console.WriteLine("Decompressed Length = " & dec.Length) ' 537 (same size!)
Console.WriteLine("Roundtrip Successful: " & (input = dec).ToString()) ' True
End Sub
Public Function DecompressString(ByVal bytes As Byte()) As String
Using ms = New MemoryStream(bytes)
Using ds = New GZipStream(ms, CompressionMode.Decompress)
Using sr = New StreamReader(ds)
Return sr.ReadToEnd()
End Using
End Using
End Using
End Function
Public Function CompressString(input As String) As Byte()
Using ms = New MemoryStream
Using cs = New GZipStream(ms, CompressionLevel.Optimal)
Dim bytes As Byte() = Encoding.UTF8.GetBytes(input)
cs.Write(bytes, 0, bytes.Length)
' *REQUIRED* Or last chunk will be omitted. Do Not call any other close Or
' flush method.
cs.Close()
Return ms.ToArray()
End Using
End Using
End Function
编辑:
对于.NET 3.5,它仍然有效(并产生一个较小的对象;尽管不那么小4.8,但它仅将我的示例数据压缩到497个字节而不是354个字节(。
。您只需要将CompressionLevel.Optimal
更改为CompressionMode.Compress
。