使用 C# 压缩/解压缩字符串 [英] Compression/Decompression string with C#
问题描述
我是 .net 的新手.我正在用 C# 做压缩和解压字符串.有一个 XML,我正在转换字符串,然后进行压缩和解压缩.我的代码中没有编译错误,除非我解压缩我的代码并返回我的字符串,它只返回 XML 的一半.
I am newbie in .net. I am doing compression and decompression string in C#. There is a XML and I am converting in string and after that I am doing compression and decompression.There is no compilation error in my code except when I decompression my code and return my string, its returning only half of the XML.
以下是我的代码,有错误的地方请指正.
Below is my code, please correct me where I am wrong.
代码:
class Program
{
public static string Zip(string value)
{
//Transform string into byte[]
byte[] byteArray = new byte[value.Length];
int indexBA = 0;
foreach (char item in value.ToCharArray())
{
byteArray[indexBA++] = (byte)item;
}
//Prepare for compress
System.IO.MemoryStream ms = new System.IO.MemoryStream();
System.IO.Compression.GZipStream sw = new System.IO.Compression.GZipStream(ms, System.IO.Compression.CompressionMode.Compress);
//Compress
sw.Write(byteArray, 0, byteArray.Length);
//Close, DO NOT FLUSH cause bytes will go missing...
sw.Close();
//Transform byte[] zip data to string
byteArray = ms.ToArray();
System.Text.StringBuilder sB = new System.Text.StringBuilder(byteArray.Length);
foreach (byte item in byteArray)
{
sB.Append((char)item);
}
ms.Close();
sw.Dispose();
ms.Dispose();
return sB.ToString();
}
public static string UnZip(string value)
{
//Transform string into byte[]
byte[] byteArray = new byte[value.Length];
int indexBA = 0;
foreach (char item in value.ToCharArray())
{
byteArray[indexBA++] = (byte)item;
}
//Prepare for decompress
System.IO.MemoryStream ms = new System.IO.MemoryStream(byteArray);
System.IO.Compression.GZipStream sr = new System.IO.Compression.GZipStream(ms,
System.IO.Compression.CompressionMode.Decompress);
//Reset variable to collect uncompressed result
byteArray = new byte[byteArray.Length];
//Decompress
int rByte = sr.Read(byteArray, 0, byteArray.Length);
//Transform byte[] unzip data to string
System.Text.StringBuilder sB = new System.Text.StringBuilder(rByte);
//Read the number of bytes GZipStream red and do not a for each bytes in
//resultByteArray;
for (int i = 0; i < rByte; i++)
{
sB.Append((char)byteArray[i]);
}
sr.Close();
ms.Close();
sr.Dispose();
ms.Dispose();
return sB.ToString();
}
static void Main(string[] args)
{
XDocument doc = XDocument.Load(@"D:RSP.xml");
string val = doc.ToString(SaveOptions.DisableFormatting);
val = Zip(val);
val = UnZip(val);
}
}
我的 XML 大小为 63KB.
My XML size is 63KB.
推荐答案
压缩/解压字符串的代码
The code to compress/decompress a string
public static void CopyTo(Stream src, Stream dest) {
byte[] bytes = new byte[4096];
int cnt;
while ((cnt = src.Read(bytes, 0, bytes.Length)) != 0) {
dest.Write(bytes, 0, cnt);
}
}
public static byte[] Zip(string str) {
var bytes = Encoding.UTF8.GetBytes(str);
using (var msi = new MemoryStream(bytes))
using (var mso = new MemoryStream()) {
using (var gs = new GZipStream(mso, CompressionMode.Compress)) {
//msi.CopyTo(gs);
CopyTo(msi, gs);
}
return mso.ToArray();
}
}
public static string Unzip(byte[] bytes) {
using (var msi = new MemoryStream(bytes))
using (var mso = new MemoryStream()) {
using (var gs = new GZipStream(msi, CompressionMode.Decompress)) {
//gs.CopyTo(mso);
CopyTo(gs, mso);
}
return Encoding.UTF8.GetString(mso.ToArray());
}
}
static void Main(string[] args) {
byte[] r1 = Zip("StringStringStringStringStringStringStringStringStringStringStringStringStringString");
string r2 = Unzip(r1);
}
记住 Zip
返回一个 byte[]
,而 Unzip
返回一个 string
.如果你想要一个来自 Zip
的字符串,你可以对它进行 Base64 编码(例如使用 Convert.ToBase64String(r1)
)(Zip
的结果是非常二进制的!它不是您可以打印到屏幕或直接写入 XML 的东西)
Remember that Zip
returns a byte[]
, while Unzip
returns a string
. If you want a string from Zip
you can Base64 encode it (for example by using Convert.ToBase64String(r1)
) (the result of Zip
is VERY binary! It isn't something you can print to the screen or write directly in an XML)
建议的版本适用于 .NET 2.0,对于 .NET 4.0 使用 MemoryStream.CopyTo
.
The version suggested is for .NET 2.0, for .NET 4.0 use the MemoryStream.CopyTo
.
重要提示: 在 GZipStream
知道它拥有所有输入(即,为了有效地压缩它需要所有输入)之前,无法将压缩内容写入输出流数据).在检查输出流(例如,mso.ToArray()
)之前,您需要确保 GZipStream
的 Dispose()
.这是通过上面的 using() { }
块完成的.请注意,GZipStream
是最里面的块,其内容是在其外部访问的.在尝试访问数据之前,解压缩:GZipStream
的 Dispose()
也是如此.
IMPORTANT: The compressed contents cannot be written to the output stream until the GZipStream
knows that it has all of the input (i.e., to effectively compress it needs all of the data). You need to make sure that you Dispose()
of the GZipStream
before inspecting the output stream (e.g., mso.ToArray()
). This is done with the using() { }
block above. Note that the GZipStream
is the innermost block and the contents are accessed outside of it. The same goes for decompressing: Dispose()
of the GZipStream
before attempting to access the data.
这篇关于使用 C# 压缩/解压缩字符串的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!