C#使用GZip压缩XML类字符串后解压报InvalidDataException问题
问题诊断与解决方案
这个错误的核心原因几乎都是压缩过程中没有正确完成GZipStream的收尾操作,或者流的位置没有正确重置,导致解压时读取的不是完整的压缩数据。
常见错误场景
很多新手会忽略在压缩后调用gzipStream.Close(),或者不用using语句包裹流对象,导致压缩数据缺少收尾标记;也可能没有将内存流的位置重置到起始点就读取压缩后的数据,导致解压时拿到的是不完整的无效数据。
正确的XML字符串压缩/解压实现
以下是经过验证的可运行代码:
using System.IO; using System.IO.Compression; using System.Text; public static class XmlCompressionHelper { // 压缩XML字符串 public static byte[] CompressXmlString(string xmlContent) { byte[] rawData = Encoding.UTF8.GetBytes(xmlContent); using (var compressedStream = new MemoryStream()) { // 使用using自动处置GZipStream,确保完成压缩收尾 using (var gzipStream = new GZipStream(compressedStream, CompressionMode.Compress, leaveOpen: true)) { gzipStream.Write(rawData, 0, rawData.Length); } // 重置流位置到起始点,保证能读取完整的压缩数据 compressedStream.Position = 0; return compressedStream.ToArray(); } } // 解压XML字符串 public static string DecompressXmlString(byte[] compressedData) { using (var compressedStream = new MemoryStream(compressedData)) using (var decompressedStream = new MemoryStream()) { using (var gzipStream = new GZipStream(compressedStream, CompressionMode.Decompress)) { gzipStream.CopyTo(decompressedStream); } // 重置流位置后读取解压内容 decompressedStream.Position = 0; using (var reader = new StreamReader(decompressedStream, Encoding.UTF8)) { return reader.ReadToEnd(); } } } }
关键修复点
- 用
using包裹GZipStream:自动完成流的收尾操作,确保写入GZip格式的完整结束标记,避免压缩数据不完整。 - 设置
leaveOpen: true(压缩阶段):防止GZipStream关闭底层的MemoryStream,保证后续可以重置位置并读取压缩后的数据。 - 重置流的
Position到0:无论是压缩后读取数据,还是解压后读取内容,都要确保流从起始位置开始读取,避免读取到空或无效的片段。
按上述逻辑修改原有代码后,即可解决解压时的InvalidDataException异常。
内容的提问来源于stack exchange,提问作者Nikola Matic
相关产品推荐
相关产品推荐

