重构C#代码后SevenZipSharp出现流无效/无签名异常的解决请求
问题根源与解决方法
你遇到的System.ArgumentException: The stream is invalid or no corresponding signature was found错误,核心原因是把二进制压缩流直接转换成普通字符串时损坏了数据,导致解压时SevenZipSharp无法识别合法的压缩签名。
为什么原代码正常,重构后出错?
原代码中压缩后的compressedMemoryStream是直接作为二进制流传递给解压逻辑的,全程没有经过字符串转换,数据保持完整。但重构后你把压缩流用StreamReader读取成普通字符串(compressedString),再把这个字符串转回流去解压——压缩后的内容是二进制字节序列,不是合法的文本编码(比如UTF-8),转换过程中会丢失或篡改部分字节,自然无法被解压识别。
正确的解决方案:用Base64编码处理二进制与字符串的转换
Base64是专门用来将二进制数据转换成ASCII字符串的编码方式,不会损坏原始数据。我们需要修改压缩和解压的字符串转换逻辑:
修正后的完整代码示例
using System; using System.IO; using System.Text; using SevenZip; namespace _7ZipWrapper { public class Program { public static void Main() { // Setup Input String var strToCompress = "This String"; // Convert input string to memory stream var memStreamToCompress = StringToStream(strToCompress); // Confirm the Input Stream is As-Expected memStreamToCompress.Position = 0; var MemoryAsString = new StreamReader(memStreamToCompress); Console.WriteLine("Stream in memory: " + MemoryAsString.ReadToEnd()); Console.ReadKey(); // Compress the Stream memStreamToCompress.Position = 0; var compressedBase64String = StreamCompress(memStreamToCompress, "password"); // Decompress the String var memStreamToRestore = Base64StringToStream(compressedBase64String); var decompressedString = StreamDecompress(memStreamToRestore, "password"); Console.WriteLine("Decompressed String: " + decompressedString); Console.ReadKey(); } // 将普通字符串转成内存流(用于原始输入) private static MemoryStream StringToStream(string strToMemoryStream) { var memoryStream = new MemoryStream(Encoding.UTF8.GetBytes(strToMemoryStream)); return memoryStream; } // 将Base64字符串转回二进制内存流(用于解压输入) private static MemoryStream Base64StringToStream(string base64Str) { var bytes = Convert.FromBase64String(base64Str); return new MemoryStream(bytes); } private static string StreamCompress(MemoryStream memStreamToCompress, string optionalPassword) { // Setup the SevenZip Dll SevenZipCompressor.SetLibraryPath(@"C:\Temp\7za64.dll"); // Set up a compressor... SevenZipCompressor sevenZip = new SevenZipCompressor(); sevenZip.CompressionMethod = CompressionMethod.Ppmd; sevenZip.CompressionLevel = CompressionLevel.Ultra; sevenZip.ScanOnlyWritable = true; // Compress PassedStream -> CompressedStream using var compressedMemoryStream = new MemoryStream(); sevenZip.CompressStream(memStreamToCompress, compressedMemoryStream, optionalPassword); // 将二进制压缩流转成Base64字符串返回 compressedMemoryStream.Position = 0; return Convert.ToBase64String(compressedMemoryStream.ToArray()); } private static string StreamDecompress(MemoryStream compressedStream, string optionalPassword) { SevenZipCompressor.SetLibraryPath(@"C:\Temp\7za64.dll"); using var decompressedMemoryStream = new MemoryStream(); using var sevenZipExtractor = new SevenZipExtractor(compressedStream, optionalPassword); sevenZipExtractor.ExtractFile(0, decompressedMemoryStream); // 将解压后的二进制流转回普通字符串 decompressedMemoryStream.Position = 0; return Encoding.UTF8.GetString(decompressedMemoryStream.ToArray()); } } }
关键修改点说明
- 压缩阶段:不再用
StreamReader读取压缩流,而是将压缩流的字节数组转成Base64字符串返回,避免二进制数据损坏。 - 解压阶段:先将Base64字符串转回二进制流,再交给SevenZipExtractor处理,保证输入流是完整的压缩数据。
- 字符串转流优化:直接用
Encoding.UTF8.GetBytes转换原始字符串,比StreamWriter更简洁高效,同时明确编码格式,避免默认编码带来的问题。
另外注意:如果你的COM DLL需要处理多语言字符串,确保统一使用UTF-8编码,避免乱码问题。
内容的提问来源于stack exchange,提问作者SlowLearner
相关产品推荐
相关产品推荐

