web-dev-qa-db-fra.com

Comment utiliser le SDK 7z pour compresser et décompresser un fichier

Selon ce lien Comment créer des archives 7-Zip avec .NET? , WOPR nous dit comment compresser un fichier avec LMZA (algorithme de compression 7z) en utilisant le SDK 7z ( 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();
      }
   }
}

Mais comment le décompresser?

J'essaie :

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

mais sans succès.

Avez-vous un exemple de travail?

Merci

PS: Selon un autre code http://www.koders.com/csharp/fid43E85EE5AE7BB255C69D18ECC3288285AD67A4A4.aspx?s=Zip+encoder#L5 , il semble que le décodeur ait besoin d'un en-tête, d'un dictionnaire à le début du fichier pour fonctionner. Ce fichier généré par Koders n'est pas une archive 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 est calculé de la même manière que leur méthode Compress. Mais comment calculer la taille de sortie autrement?

23
Djax

Cette question est un peu ancienne, mais google ne fournit pas de réponse satisfaisante, c'est donc pour ceux comme moi qui la recherchent encore. Si vous regardez dans le dossier LMZAAlone du SDK, il y a du code qui compresse et décompresse les fichiers. En l'utilisant comme exemple, il semblerait que vous deviez écrire et lire les propriétés de l'encodeur et décompresser la taille du fichier dans votre fichier de sortie:

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

Notez que les fichiers créés de cette façon peuvent également être extraits par le programme 7Zip mais ne conserveront pas leur nom de fichier ni aucune autre métadonnée.

33
Fr33dan

Je recommande fortement managed-lzma:
https://github.com/weltkante/managed-lzma

Il préserve les informations sur les fichiers et la structure des répertoires dans l'encodage des fichiers.

3
SepehrM