Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
646 views
in Technique[技术] by (71.8m points)

c# - How to use the 7z SDK to compress and decompress a file

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?

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

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.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...