课程计划 { 公共静态字符串Zip(字符串值) { //将字符串转换为字节[] byte[]字节数组=新字节[value.Length]; int索引BA=0; foreach(value.ToCharArray()中的字符项) { byteArray[indexBA++]=(字节)项; } //准备压缩 系统。 IO.MemoryStream ms=新系统。 IO.MemoryStream(); 系统。 IO.压缩。 GZipStream sw=新系统。 IO.压缩。 GZipStream(毫秒,System.IO.Compression。CompressionMode.Compression); //压缩 西南部。 写入(byteArray,0,byteArray.Length); //关闭,请勿刷新,因为字节将丢失。。。 西南部。 关闭(); //将字节[]zip数据转换为字符串 byteArray=毫秒ToArray(); 系统。 文本。 StringBuilder sB=新系统。 文本。 StringBuilder(byteArray.Length); foreach(字节数组中的字节项) { sB.Append((char)item); } 毫秒关闭(); 西南部。 处置(); ms.Dispose(); return sB.ToString(); } 公共静态字符串UnZip(字符串值) { //将字符串转换为字节[] byte[]字节数组=新字节[value.Length]; int索引BA=0; foreach(value.ToCharArray()中的字符项) { byteArray[indexBA++]=(字节)项; } //准备减压 系统。 IO.MemoryStream ms=新系统。 IO.MemoryStream(字节数组); 系统。 IO.压缩。 GZipStream sr=新系统。 IO.压缩。 GZipStream(毫秒, 系统。 IO压缩。 压缩模式。 减压); //重置变量以收集未压缩的结果 byteArray=新字节[byteArray.Length]; //解压缩 int rByte=sr.Read(byteArray,0,byteArray.Length); //转换byte[]将数据解压缩为字符串 系统。 文本。 StringBuilder sB=新系统。 文本。 字符串生成器(rByte); //读取GZipStream red的字节数,而不是中的每个字节 //resultByteArray; for(int i=0;i<rByte;i++) { sB.Append((char)byteArray[i]); } sr.关闭(); 毫秒关闭(); sr.处置(); ms.Dispose(); return sB.ToString(); } static void Main(字符串[]参数) { XDocument文档=XDocument。 加载(@“D:\RSP.xml”); 字符串val=文档。 ToString(SaveOptions.DisableFormatting); val=邮政编码(val); val=解压缩(val); } }
-
2 我怀疑如果使用 UTF8编码 (或UTF16或诸如此类)和GetBytes/GetString。这也将大大简化代码。 还建议使用 使用 . – 用户166390 评论 2011年9月8日5:36 -
1 你不能像你那样把字符转换成字节,反之亦然(使用简单的转换)。 您需要使用编码,并使用相同的编码进行压缩/解压缩。 请参阅下面的xanatos答案。 – 西蒙·穆里埃 评论 2011年9月8日6:10 -
@pst不,不会的; 你会用 编码 走错了路。 根据克萨纳托斯的回答,这里你需要64垒 – 马克·格雷维尔 评论 2011年9月8日6:18 -
@Marc Gravell True错过了签名/意图的那部分。 绝对不是我首选的签名。 – 用户166390 评论 2011年9月8日7:06
8个答案
public static void CopyTo(流src,流dest){ byte[]字节=新字节[4096]; 国际碳纳米管; while((cnt=src.Read(字节,0,字节长度))!= 0) { 目的地。 写入(字节,0,cnt); } } 公共静态字节[]Zip(string str){ var bytes=编码。 UTF8.获取字节(str); 使用(var msi=新内存流(字节)) using(var mso=new MemoryStream()){ using(var gs=新GZipStream(mso,CompressionMode.Compress)){ //msi。 抄送(gs); CopyTo(msi,gs); } 返回mso。 ToArray(); } } 公共静态字符串解压缩(字节[]字节){ using(var msi=新内存流(字节)) using(var mso=new MemoryStream()){ using(var gs=新GZipStream(msi,CompressionMode.Decompress)){ //gs.复制到(mso); CopyTo(gs,mso); } return编码。 UTF8.GetString(mso.ToArray()); } } static void Main(字符串[]参数){ byte[]r1=Zip(“StringStringString字符串StringStringeStringStriNGStringStriingStringStrinkStringStriNG”); 字符串r2=解压缩(r1); }
-
谢谢你的回复。 当我使用你的代码时,它给了我编译错误。 “CopyTo()没有命名空间或程序集引用。”。 之后,我在谷歌上搜索并找到了它的CopyTo()部分。 NET 4框架。但我正在使用.NET 2.0和3.5框架。请建议我。:) – 莫希特·库玛 评论 2011年9月8日7:19 -
1 -
1 请注意,如果字符串包含代理项对,这将失败(unzipped-string!=original),例如。 string s=“X\uD800Y” 。我注意到,如果我们将“编码”更改为UTF7,它会起作用……但使用UTF7时,我们确定可以表示所有字符吗? 评论 2015年1月15日11:17 -
1 @我检查过的Pan.student,它似乎与我生成的gz文件一起工作。 这个文件可能不是真正的gz文件。 请注意,gz文件不是rar文件,不是zip文件,也不是bz2文件。 它们都是不兼容的格式。 如果你能从Windows打开它,那么我建议你在SO发布你正在使用的代码时发布一个问题。 – 萨纳托斯 评论 2015年4月13日7:43 -
1
使用系统; 使用系统。 信息作战; 使用系统。 IO.压缩; 使用系统。 文本; 命名空间CompressString { 内部静态类StringCompressor { ///<摘要> ///压缩字符串。 ///</summary> ///<param name=“text”>文本</ 参数> ///<返回> 公共静态字符串CompressString(字符串文本) { byte[]buffer=编码。 UTF8.获取字节(文本); var memoryStream=新的memoryStream(); using(var gZipStream=新的GZipStreat(memoryStream,CompressionMode.Compress,true)) { gZipStream。 写入(buffer,0,buffer.Length); } 内存流。 位置=0; var compressedData=新字节[memoryStream.Length]; 内存流。 读取(compressedData,0,compressedData.Length); var gZipBuffer=新字节[compressedData.Length+4]; 缓冲区。 块复制(compressedData,0,gZipBuffer,4,compressedData.Length); 缓冲区。 块复制(BitConverter.GetBytes(buffer.Length),0,gZipBuffer,0,4); return转换。 ToBase64String(gZipBuffer); } ///<摘要> ///解压缩字符串。 ///</summary> ///<param name=“compressedText”>压缩文本</ 参数> ///<返回> 公共静态字符串DecompressString(string compressedText) { byte[]gZipBuffer=转换。 来自Base64String(压缩文本); 使用(var memoryStream=新的memoryStream()) { int dataLength=位转换器。 ToInt32(gZipBuffer,0); 内存流。 写入(gZipBuffer,4,gZipBuffer.Length-4); var buffer=新字节[dataLength]; 内存流。 位置=0; 使用(var gZipStream=新gZipStream(memoryStream,CompressionMode.Descress)) { gZipStream。 读取(buffer,0,buffer.Length); } return编码。 UTF8.GetString(缓冲区); } } } }
-
三 -
4 -
2 -
1 -
4
公共静态类StringCompression { ///<摘要> ///压缩字符串并返回deflate压缩的Base64编码字符串。 ///</summary> ///要压缩的字符串 公共静态字符串Compress(string uncompressedString) { byte[]压缩字节; using(var uncompessedStream=new MemoryStream(编码.UTF8.GetBytes(uncompressedString)) { using(var compressedStream=new MemoryStream()) { //将leaveOpen参数设置为true,以确保在释放compressorStream时compressedStream不会关闭 //这允许compressorStream关闭其缓冲区并将其刷新到compressedStream,并确保compressedStream。 之后可以调用ToArray() //尽管MSDN文档声明ToArray()可以在关闭的MemoryStream上调用,但我不想依赖这种非常奇怪的行为 using(var compressorStream=新的DeflateStream(compressedStream,CompressionLevel.Fastest,true)) { uncompressedStream。 CopyTo(压缩流); } //调用compressedStream。 封闭DeflateStream关闭并将其缓冲区刷新为compressedStream后的ToArray() compressedBytes=压缩流。 ToArray(); } } return转换。 ToBase64String(压缩字节); } ///<摘要> ///解压缩deflate压缩的Base64编码字符串,并返回未压缩的字符串。 ///</summary> ///<param name=“compressedString”>要解压缩的字符串</ 参数> 公共静态字符串解压缩(string compressedString) { byte[]解压缩字节; var compressedStream=新的MemoryStream(Convert.FromBase64String(compressedString)); using(var decompressorStream=新的DeflateStream(compressedStream,CompressionMode.Decompress)) { using(var decompressedStream=new MemoryStream()) { 解压缩或流。 CopyTo(解压缩流); decompressedBytes=解压缩流。 ToArray(); } } return编码。 UTF8.GetString(解压缩字节); } }
var uncompressedString=“Hello World!”; var compressedString=解压缩String.Compress();
var decompressedString=压缩字符串.Decompress();
公共静态类扩展 { ///<摘要> ///压缩字符串并返回deflate压缩的Base64编码字符串。 ///</summary> ///要压缩的字符串 公共静态字符串Compress(此字符串为uncompressedString) { byte[]压缩字节; using(var uncompessedStream=new MemoryStream(编码.UTF8.GetBytes(uncompressedString)) { using(var compressedStream=new MemoryStream()) { //将leaveOpen参数设置为true,以确保在释放compressorStream时compressedStream不会关闭 //这允许compressorStream关闭其缓冲区并将其刷新到compressedStream,并确保compressedStream。 之后可以调用ToArray() //尽管MSDN文档声明ToArray()可以在关闭的MemoryStream上调用,但我不想依赖这种非常奇怪的行为 using(var compressorStream=新的DeflateStream(compressedStream,CompressionLevel.Fastest,true)) { uncompressedStream。 CopyTo(压缩流); } //调用compressedStream。 封闭的DeflateStream关闭并将其缓冲区刷新为compressedStream之后的ToArray() compressedBytes=压缩流。 ToArray(); } } return转换。 ToBase64String(压缩字节); } ///<摘要> ///解压缩deflate压缩的Base64编码字符串,并返回未压缩的字符串。 ///</summary> ///<param name=“compressedString”>要解压缩的字符串</ 参数> 公共静态字符串解压缩(此字符串compressedString) { byte[]解压缩字节; var compressedStream=新内存流(Convert.FromBase64String(compressedString)); using(var decompressorStream=新的DeflateStream(compressedStream,CompressionMode.Decompress)) { using(var decompressedStream=new MemoryStream()) { 解压缩或流。 CopyTo(解压缩流); 解压缩字节=解压缩流。 ToArray(); } } return编码。 UTF8.GetString(解压缩字节); } }
-
2 杰斯:我想你失踪了 使用 MemoryStream实例的语句。 对于F#开发人员:避免使用关键字 使用 对于compressorStream/decompressorStream实例,因为它们需要在 ToArray() 被呼叫 – 纽克特 评论 2018年8月15日17:13 -
1 -
2 @迈克尔·弗雷德吉姆(Michael Freidgeim):我认为压缩和解压缩内存流是不可能的。 对于文件或不可靠的传输,这是有意义的。 我要说的是,在我的特定用途中,高速是非常理想的,因此我可以避免任何开销。 – 杰斯 评论 2018年11月22日3:58 -
1 -
1 @塞巴斯蒂安阅读了文档: learn.microsoft.com/en-us/dotnet/api/… 默认情况下,DeflateStream拥有基础流,因此关闭流也会关闭基础流 – 杰斯 评论 2019年4月25日16:14
公共静态类ZipExtensions { 公共静态字符串CompressToBase64(此字符串数据) { return转换。 ToBase64String(编码.UTF8.GetBytes(数据))。 压缩()); } 公共静态字符串DecompressFromBase64(此字符串数据) { return编码。 UTF8.GetString(转换.FromBase64String(数据)。 解压缩(); } 公共静态字节[]压缩(此字节[]数据) { using(var sourceStream=新内存流(数据)) using(var destinationStream=new MemoryStream()) { 源流。 压缩到(destinationStream); return destinationStream。 ToArray(); } } 公共静态字节[]解压缩(此字节[]数据) { using(var sourceStream=新内存流(数据)) using(var destinationStream=new MemoryStream()) { 源流。 解压缩到(destinationStream); return destinationStream。 ToArray(); } } public static void CompressTo(此Stream流,Stream outputStream) { using(var gZipStream=新的GZipStreat(outputStream,CompressionMode.Compress)) { 流。 CopyTo(gZipStream); gZipStream。 冲洗(); } } public static void DecompressTo(此Stream流,Stream outputStream) { using(var gZipStream=新的GZipStreat(stream,CompressionMode.Decompress)) { gZipStream。 CopyTo(outputStream); } } }
公共静态类CompressionExtensions { 公共静态异步任务<IEnumerable<byte>>Zip(此对象obj) { byte[]字节=obj.Serialize(); using(MemoryStream msi=新的MemoryStrem(字节)) using(MemoryStream mso=new MemoryStream()) { using(var gs=新GZipStream(mso,CompressionMode.Compress)) 等待msi。 复制到异步(gs); 返回mso。 ToArray()。 AsEnumerable(); } } 公共静态异步任务<object>Unzip(this byte[]bytes) { using(MemoryStream msi=新的MemoryStrem(字节)) using(MemoryStream mso=new MemoryStream()) { using(var gs=新GZipStream(msi,CompressionMode.Decompress)) { //同步示例: //gs.复制到(mso); //异步方式(注意在方法定义中使用Async关键字) 等待gs.CopyToAsync(mso); } 返回mso。 ToArray()。 反序列化(); } } } 公共静态类SerializerExtensions { 公共静态字节[]序列化<T>(此T对象ToWrite) { using(MemoryStream流=new MemoryStream()) { BinaryFormatter BinaryFormatter=新的BinaryFormatter(); 二进制格式设置工具。 序列化(流,objectToWrite); 回流。 GetBuffer(); } } 公共静态异步任务<T>_串行化<T>(此字节[]arr) { using(MemoryStream流=new MemoryStream()) { BinaryFormatter BinaryFormatter=新的BinaryFormatter(); 等待流。 WriteAsync(arr,0,arr.Length); 流。 位置=0; return(T)二进制格式设置工具。 反序列化(流); } } public static async Task<object>反序列化(this byte〔〕arr) { object obj=等待arr._Deserialize<对象>(); 返回对象; } }
-
-
值得注意的是,这种方法有效,但仅适用于基于UTF8的东西。 例如,如果您在序列化/反序列化的字符串值中添加类似于aäö的瑞典字符,它将无法通过往返测试:/ – bc3技术 评论 2019年8月21日12:32 -
在这种情况下,您可以使用 转换。 ToBase64String(字节[]) 请看这个答案( stackoverflow.com/a/23908465/3286975 ). 希望它能有所帮助! 评论 2019年8月22日2:31
公共静态字符串decodeDecompress(string originalReceivedSrc){ byte[]字节=转换。 来自Base64String(原始接收Src); using(var mem=new MemoryStream()){ //诀窍就在这里 成员。 写入(新字节[]{0x1f、0x8b、0x08、0x00、0x00,0x00、x00}、0、8); 成员。 写入(字节,0,字节。长度); 成员。 位置=0; using(var gzip=新的GZipStream(mem,CompressionMode.Decompress)) using(var reader=新StreamReader(gzip)){ 返回读取器。 ReadToEnd(); } } }
-
我得到这个异常:抛出异常:“System。 System.dll中的IO.InvalidDataException“其他信息:GZip页脚中的CRC与从解压缩数据计算的CRC不匹配。 评论 2016年9月2日9:02 -
我相信有人会面临同样的问题。 要在压缩字符串中使用这个神奇的头,需要使用适当的php函数:“gzencode”而不是“gzcompress”。 PHP中还有另一种压缩算法:“gziflate”,但我个人从未使用过。附言:您的代码有一个问题:您编写了一个标头,然后通过将偏移量0设置为第二个Write()方法,用实际字节覆盖它,因此流中的字节相同。 – 开发商 评论 2021年9月10日5:28
#区域辅助对象 私有字节[]Zip(字符串文本) { if(文本==空) 返回null; 字节[]ret; using(var outputMemory=new MemoryStream()) { using(var gz=新GZipStream(outputMemory,CompressionLevel.Optimal)) { using(var sw=新StreamWriter(gz,Encoding.UTF8)) { 西南部。 写(文本); } } ret=输出内存。 ToArray(); } 返回ret; } 私有字符串解压缩(字节[]字节) { 字符串ret=空; using(var inputMemory=新内存流(字节)) { using(var gz=新GZipStream(inputMemory,CompressionMode.Decompress)) { using(var sr=新StreamReader(gz,Encoding.UTF8)) { ret=sr.ReadToEnd(); } } } 返回ret; } #端部区域
公共静态字节[]Zip(字符串未压缩) { 字节[]ret; using(var outputMemory=new MemoryStream()) { using(var gz=新GZipStream(outputMemory,CompressionLevel.Optimal)) { using(var sw=新StreamWriter(gz,Encoding.UTF8)) { 软件。 写入(未压缩); } } ret=输出内存。 ToArray(); } 返回ret; } 公共静态字符串解压缩(字节[]已压缩) { 字符串ret=空; using(var inputMemory=new MemoryStream(压缩)) { using(var gz=新GZipStream(inputMemory,CompressionMode.Decompress)) { using(var sr=新StreamReader(gz,Encoding.UTF8)) { ret=sr.ReadToEnd(); } } } 返回ret; }