如何使用7z SDK压缩和解压文件

发布于 2024-12-07 16:32:46 字数 2368 浏览 2 评论 0原文

根据此链接 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 ,看来解码器需要一个 header,开头的一个字典文件工作。 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 方法相同。但是如何计算输出大小呢?

According to this link How do I create 7-Zip archives with .NET? , WOPR tell us how to compress a file with LMZA (7z compression algorithm) using 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();
      }
   }
}

But how to decompress it?

I try :

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();
                }
            }
        }

but without success.

Do you have a working example?

Thanks

PS:
According to an other code http://www.koders.com/csharp/fid43E85EE5AE7BB255C69D18ECC3288285AD67A4A4.aspx?s=zip+encoder#L5 , it seems that the decoder needs a header, a dictionary at the beginning of the file to work. This file generated by Koders is not a 7z archive.

   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);
    }

The outSize is computed the same way than their Compress method. But how to compute the output size otherwise?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

爱她像谁 2024-12-14 16:32:46

这个问题有点老了,但谷歌未能提供令人满意的答案,所以这适合像我这样仍在寻找答案的人。如果您查看 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 程序提取,但不会保留其文件名或任何内容其他元数据。

This question is a little old, but google fails to provide a satisfactory answer so this is for those like me still seeking it out. If you look into the LMZAAlone folder of the SDK there is code that compresses and decompresses files. Using it as an example it would seem you need to write and read the encoder properties and decompresses file size to your output file:

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();
    }

Note that the files created this way can be extracted by the 7zip program as well but will not retain their filename or any other metadata.

牵你的手,一向走下去 2024-12-14 16:32:46

我需要 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();
        }
    }
  }

I needed LZMA compression for sending images over network, not sure it's the best alternative but at least it works in my ecosystem! So here is something that should work right away for that purpose.

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();
        }
    }
  }
掩于岁月 2024-12-14 16:32:46

我强烈推荐 Managed-lzma:
它将

文件信息和目录结构保存在文件编码。

I highly recommend managed-lzma:
https://github.com/weltkante/managed-lzma

It preserves file info and directory structure in file encoding.

骄傲 2024-12-14 16:32:46

类似于@Dominic Grenier 解决方案。解压缩器必须知道使用哪些属性来解压缩有效负载。您有责任对它们进行序列化/反序列化。

public static void 
Compress7Zip(this 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 static void 
Decompress7Zip(this 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);
}

Similar to @Dominic Grenier solution. Decompressor must know which properties to use to decompress the payload. This is your responsibility to serialize/deserialize them.

public static void 
Compress7Zip(this 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 static void 
Decompress7Zip(this 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);
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文