簡體   English   中英

如何使用 7z SDK 壓縮和解壓文件

[英]How to use the 7z SDK to compress and decompress a file

根據此鏈接如何使用 .NET 創建 7-Zip 檔案? , 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 方法相同。 但是否則如何計算輸出大小?

這個問題有點老了,但谷歌未能提供令人滿意的答案,所以這適合像我這樣仍在尋找它的人。 如果您查看 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:
https://github.com/weltkante/managed-lzma

它在文件編碼中保留文件信息和目錄結構。

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

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM