根据此链接 How do I create 7-Zip archives with .NET? ,WOPR 告诉我们如何使用 7z SDK ( http://www.7-zip. org/sdk.html)
using SevenZip.Compression.LZMA;
private static void CompressFileLZMA(string inFile, string outFile)
{
SevenZip.Compression.LZMA.Encoder coder = new SevenZip.Compression.LZMA.Encoder();
using (FileStream input = new FileStream(inFile, FileMode.Open))
{
using (FileStream output = new FileStream(outFile, FileMode.Create))
{
coder.Code(input, output, -1, -1, null);
output.Flush();
}
}
}
但是如何解压呢?
我尝试:
private static void DecompressFileLZMA(string inFile, string outFile)
{
SevenZip.Compression.LZMA.Decoder coder = new SevenZip.Compression.LZMA.Decoder();
using (FileStream input = new FileStream(inFile, FileMode.Open))
{
using (FileStream output = new FileStream(outFile, FileMode.Create))
{
coder.Code(input, output, input.Length, -1, null);
output.Flush();
}
}
}
但没有成功。
你有一个可行的例子吗?
谢谢
PS: 根据其他代码http://www.koders.com/csharp/fid43E85EE5AE7BB255C69D18ECC3288285AD67A4A4.aspx?s=zip+encoder#L5,似乎解码器需要一个标头,文件开头的字典才能工作。 Koders 生成的此文件不是 7z 存档。
public static void Decompress(Stream inStream, Stream outStream)
{
byte[] properties = new byte[5];
inStream.Read(properties, 0, 5);
SevenZip.Compression.LZMA.Decoder decoder = new SevenZip.Compression.LZMA.Decoder();
decoder.SetDecoderProperties(properties);
long outSize = 0;
for (int i = 0; i < 8; i++)
{
int v = inStream.ReadByte();
outSize |= ((long)(byte)v) << (8 * i);
}
long compressedSize = inStream.Length - inStream.Position;
decoder.Code(inStream, outStream, compressedSize, outSize, null);
}
outSize 的计算方式与其 Compress 方法相同。但是如何计算输出大小呢?
这个问题有点老了,但谷歌未能提供令人满意的答案,所以这适合像我这样仍在寻找答案的人。如果您查看 SDK 的 LMZAAlone 文件夹,就会发现压缩和解压缩文件的代码。以它为例,您似乎需要写入和读取编码器属性并将文件大小解压缩到输出文件:
private static void CompressFileLZMA(string inFile, string outFile)
{
SevenZip.Compression.LZMA.Encoder coder = new SevenZip.Compression.LZMA.Encoder();
FileStream input = new FileStream(inFile, FileMode.Open);
FileStream output = new FileStream(outFile, FileMode.Create);
// Write the encoder properties
coder.WriteCoderProperties(output);
// Write the decompressed file size.
output.Write(BitConverter.GetBytes(input.Length), 0, 8);
// Encode the file.
coder.Code(input, output, input.Length, -1, null);
output.Flush();
output.Close();
}
private static void DecompressFileLZMA(string inFile, string outFile)
{
SevenZip.Compression.LZMA.Decoder coder = new SevenZip.Compression.LZMA.Decoder();
FileStream input = new FileStream(inFile, FileMode.Open);
FileStream output = new FileStream(outFile, FileMode.Create);
// Read the decoder properties
byte[] properties = new byte[5];
input.Read(properties, 0, 5);
// Read in the decompress file size.
byte [] fileLengthBytes = new byte[8];
input.Read(fileLengthBytes, 0, 8);
long fileLength = BitConverter.ToInt64(fileLengthBytes, 0);
coder.SetDecoderProperties(properties);
coder.Code(input, output, input.Length, fileLength, null);
output.Flush();
output.Close();
}
请注意,以这种方式创建的文件也可以由 7zip 程序提取,但不会保留其文件名或任何其他元数据。
我需要 LZMA 压缩来通过网络发送图像,不确定它是最好的选择,但至少它在我的生态系统中有效!因此,这里有一些应该可以立即用于此目的的东西。
using System;
using System.IO;
using SevenZip;
public class LZMA{
public static byte[] Compress(byte[] toCompress)
{
SevenZip.Compression.LZMA.Encoder coder = new SevenZip.Compression.LZMA.Encoder();
using(MemoryStream input = new MemoryStream(toCompress))
using(MemoryStream output = new MemoryStream()){
coder.WriteCoderProperties(output);
for (int i = 0; i < 8; i++) {
output.WriteByte((byte)(input.Length >> (8 * i)));
}
coder.Code(input, output, -1, -1, null);
return output.ToArray();
}
}
public static byte[] Decompress(byte[] toDecompress)
{
SevenZip.Compression.LZMA.Decoder coder = new SevenZip.Compression.LZMA.Decoder();
using(MemoryStream input = new MemoryStream(toDecompress))
using(MemoryStream output = new MemoryStream()){
// Read the decoder properties
byte[] properties = new byte[5];
input.Read(properties, 0, 5);
// Read in the decompress file size.
byte [] fileLengthBytes = new byte[8];
input.Read(fileLengthBytes, 0, 8);
long fileLength = BitConverter.ToInt64(fileLengthBytes, 0);
coder.SetDecoderProperties(properties);
coder.Code(input, output, input.Length, fileLength, null);
return output.ToArray();
}
}
}
我强烈推荐托管-lzma:
https://github.com/weltkante/management-lzma
它以文件编码形式保留文件信息和目录结构。
类似于@Dominic Grenier 解决方案。解串器必须知道使用哪些属性来解压缩有效负载。您有责任对它们进行序列化/反序列化。
public void
Compress(Stream input, Stream output) {
var coder = new SevenZip.Compression.LZMA.Encoder();
coder.WriteCoderProperties(output);
output.WriteInt64(input.Length);
coder.Code(input, output, -1, -1, null);
}
public void
Decompress(Stream input, Stream output) {
var coder = new SevenZip.Compression.LZMA.Decoder();
var properties = new byte[5];
input.Read(properties, 0, 5);
var payloadLength = input.ReadInt64();
coder.SetDecoderProperties(properties);
coder.Code(input, output, input.Length, payloadLength, null);
}