Using 7zip sdk to compress the file but cannot unzip it using winrar or 7zip

I downloaded the 7zip SDK from here .

Then I used this code to compress the file to 7zip:

private static void CompressFileLZMA(string inFile, string outFile) { 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(); } } 

I tried both the SDK version of version 9.20 and 9.22 on the site.

Compression seems to work to compress my file: from 1.6 MB to 239 KB.

However, if I use WinRar or 7zip for unpacking. the archive file is not recognized by them, the error is similar to

"unknown archive file or damaged file"

Any idea for this?

+4
source share
3 answers

You can try using the 7zSharp shell, or at least parse the wrapper code, as it is done.

Code for file compression (taken from 7zSharp):

  public void EncodeSingleFile(string inFile, string outFile) { using (FileStream inStream = new FileStream(inFile, FileMode.Open, FileAccess.Read)) { using (FileStream outStream = new FileStream(outFile, FileMode.OpenOrCreate, FileAccess.Write)) { EncodeSingleFile(inStream, outStream); } } } public void EncodeSingleFile(FileStream inStream, FileStream outStream) { bool eos = false; Int32 dictionary = 1 << 21; Int32 posStateBits = 2; Int32 litContextBits = 3; // for normal files // UInt32 litContextBits = 0; // for 32-bit data Int32 litPosBits = 0; // UInt32 litPosBits = 2; // for 32-bit data Int32 algorithm = 2; Int32 numFastBytes = 128; string mf = "bt4"; propIDs = new CoderPropID[] { CoderPropID.DictionarySize, CoderPropID.PosStateBits, CoderPropID.LitContextBits, CoderPropID.LitPosBits, CoderPropID.Algorithm, CoderPropID.NumFastBytes, CoderPropID.MatchFinder, CoderPropID.EndMarker }; properties = new object[] { dictionary, posStateBits, litContextBits, litPosBits, algorithm, numFastBytes, mf, eos }; Encoder encoder = new Encoder(); encoder.SetCoderProperties(propIDs, properties); encoder.WriteCoderProperties(outStream); Int64 fileSize = inStream.Length; for (int i = 0; i < 8; i++) { outStream.WriteByte((Byte) (fileSize >> (8*i))); } encoder.Code(inStream, outStream, -1, -1, null); } 
+2
source

Have you looked at an example project included in the SDK? It is located in the CS\7zip\Compress\LzmaAlone\ and contains the LmzaAlone.cs file, which contains material that encodes the file. It does such things before writing compressed data:

 CoderPropID[] propIDs = { CoderPropID.DictionarySize, CoderPropID.PosStateBits, CoderPropID.LitContextBits, CoderPropID.LitPosBits, CoderPropID.Algorithm, CoderPropID.NumFastBytes, CoderPropID.MatchFinder, CoderPropID.EndMarker }; object[] properties = { (Int32)(dictionary), (Int32)(posStateBits), (Int32)(litContextBits), (Int32)(litPosBits), (Int32)(algorithm), (Int32)(numFastBytes), mf, eos }; Compression.LZMA.Encoder encoder = new Compression.LZMA.Encoder(); encoder.SetCoderProperties(propIDs, properties); encoder.WriteCoderProperties(outStream); if (trainStream != null) { CDoubleStream doubleStream = new CDoubleStream(); doubleStream.s1 = trainStream; doubleStream.s2 = inStream; doubleStream.fileIndex = 0; inStream = doubleStream; long trainFileSize = trainStream.Length; doubleStream.skipSize = 0; if (trainFileSize > dictionary) doubleStream.skipSize = trainFileSize - dictionary; trainStream.Seek(doubleStream.skipSize, SeekOrigin.Begin); encoder.SetTrainSize((uint)(trainFileSize - doubleStream.skipSize)); } // only now does it write out the compressed data: encoder.Code(inStream, outStream, -1, -1, null); 

it looks like you need to write a few file headers first to provide detailed information about the compression data that will come in.

if you download the source for 7Zip , then you will find that in the doc folder there is a file 7zFormat.txt , which contains a description of the format of 7 ZIP files. This can help you create reliable archives.

+4
source

The fact that it works at the Stream level suggests that it simply follows the lzm compression / decompression logic and does not create the actual archive (the archive would be a .zip or .7z file). Like using GZipStream or DeflateStream - it does not create an archive. Tools like WinRar and 7zip work with archives.

I expect that there is another type in this API that actually creates the archive, but will expect more information, such as file names (it will almost certainly accept multiple files / streams too).

+3
source

Source: https://habr.com/ru/post/1384079/


All Articles