【问题标题】:How to use the 7z SDK to compress and decompress a file如何使用 7z SDK 压缩和解压文件
【发布时间】:2011-10-04 10:14:23
【问题描述】:

根据此链接How do I create 7-Zip archives with .NET?,WOPR 告诉我们如何使用 7z SDK (http://www.7-zip.org/sdk.html) 使用 LMZA(7z 压缩算法)压缩文件

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 方法相同。但是如何计算输出大小?

【问题讨论】:

  • 有例外吗?错误信息?
  • 我在类 LiteralDecoder 的 Init() 中的 m_Coders[i].Init(); 上得到 NullReferenceException
  • 这里也有更完整的答案:stackoverflow.com/a/8775927/220904

标签: c# sdk 7zip compression lzma


【解决方案1】:

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

【讨论】:

  • 我知道这是一个旧评论(和帖子),但我尝试了这段代码,但它不起作用。打开新存档文件时,Windows 10 说它无效并且不会打开它。
  • 我尝试使用最新版本的 7zip 程序和库,它仍然对我有用。你是什​​么意思Windows 10说它无效?您是否尝试使用 Windows 资源管理器中内置的压缩​​文件查看器打开文件?我不认为它支持 7zip/LZMA。
  • 原来 Windows 10 的存档查看器不支持 .7z。您的代码有效,但是,在提取归档文件时,文件扩展名似乎不存在,即使它包含在输入字符串中。该文件仍然有效,只是缺少扩展名;你怎么能纠正这个?
  • 答案中说文件名和所有其他元数据都丢失了。这个问题和答案是关于使用 7zip sdk 解压缩文件的问题,使用 7zip 应用程序解压缩文件的问题超出了这个问题的范围。我们创建的文件完全可以用程序提取出来,这是一个意想不到的好处。
  • 这篇文章不正确并导致存档损坏: output.Write(BitConverter.GetBytes(input.Length), 0, 8);将其替换为: for (int i = 0; i > (8 * i))); }
【解决方案2】:

我强烈推荐 managed-lzma:
https://github.com/weltkante/managed-lzma

它在文件编码中保留文件信息和目录结构。

【讨论】:

    【解决方案3】:

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-05-30
      • 2019-09-17
      • 1970-01-01
      • 2018-10-02
      • 2016-05-01
      • 1970-01-01
      相关资源
      最近更新 更多