如何在PowerShell中对7zip(LZMA2)压缩字符串实现内存解压?
PowerShell内存解压LZMA2/7z/xz格式数据方案
现有代码核心问题
现有代码存在两个核心错误导致无法解压:
- 二进制资源读取逻辑错误:使用
ReadAsStringAsync()读取xz二进制压缩包后再转码回字节数组,编码映射过程会损坏原始二进制数据,应直接读取字节流。 - 解压类不匹配:
GzipStream仅支持gzip格式压缩流,无法处理LZMA2算法的xz/7z格式流。
方案1:.NET原生XZStream实现(推荐,无第三方依赖)
适用于PowerShell 7+(基于.NET Core 3.0+/.NET 5+版本),原生自带System.IO.Compression.XZStream支持LZMA2算法的xz格式解压,全程内存操作无需写入文件:
Add-Type -AssemblyName System.Net.Http $handler = [System.Net.Http.HttpClientHandler]::new() $client = [System.Net.Http.HttpClient]::new($handler) # 直接读取二进制字节数组,避免编码转换破坏数据 $url = [string]::Concat('http://www.', 'vuplus', '-', 'community.net', '/ryt', 'ec/ryt', 'ecDE_Basic', '.xz') $response = $client.GetAsync($url).Result $compressedBytes = $response.Content.ReadAsByteArrayAsync().Result # 内存解压xz流 $inputStream = [System.IO.MemoryStream]::new($compressedBytes) $outputStream = [System.IO.MemoryStream]::new() $xzStream = [System.IO.Compression.XZStream]::new($inputStream, [System.IO.Compression.CompressionMode]::Decompress) $xzStream.CopyTo($outputStream) $uncompressedBytes = $outputStream.ToArray() # 按实际文件编码转换为字符串,示例为ISO-8859-1(编码代号28591) $enc = [System.Text.Encoding]::GetEncoding(28591) $unzippedText = $enc.GetString($uncompressedBytes)
方案2:调用7za.dll实现内存解压(兼容Windows PowerShell)
如果使用的是Windows PowerShell(基于.NET Framework 4.x,无原生XZStream支持),可以调用7-Zip官方的7za.dll完成纯内存解压,无需写入文件系统:
- 提前获取对应系统架构的7za.dll,加载到PowerShell进程中
- 复用7-Zip官方SDK提供的LZMA2解压C#实现,内嵌到PowerShell的
Add-Type中直接调用,传入压缩字节数组即可返回解压后的字节数组
示例代码框架:
Add-Type @" // 此处粘贴7-Zip官方SDK中LZMA2解压的C#实现,直接接收字节数组输入,返回解压后字节数组,无文件操作逻辑 "@ # 读取二进制压缩字节数组逻辑同方案1 $compressedBytes = $response.Content.ReadAsByteArrayAsync().Result $uncompressedBytes = [LZMA2Decompressor]::Decompress($compressedBytes) $unzippedText = [System.Text.Encoding]::GetEncoding(28591).GetString($uncompressedBytes)
注:如果需要处理多文件的7z归档包而非单文件xz压缩流,需额外解析7z归档结构,使用7za.dll的全功能接口即可实现纯内存操作。
内容的提问来源于stack exchange,提问作者Carsten
相关产品推荐
相关产品推荐

