2011-10-04 35 views
15

De acuerdo con este enlace How do I create 7-Zip archives with .NET?, WOPR nos dice cómo comprimir un archivo con LMZA (algoritmo de compresión 7z) usando 7z SDK (http://www.7-zip.org/sdk.html)Cómo utilizar el SDK 7z para comprimir y descomprimir un archivo

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

Pero cómo descomprimirlo?

Trato:

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

pero sin éxito.

¿Tiene un ejemplo de trabajo?

Gracias

PS: De acuerdo con otro código http://www.koders.com/csharp/fid43E85EE5AE7BB255C69D18ECC3288285AD67A4A4.aspx?s=zip+encoder#L5, parece que el descodificador necesita un encabezado, un diccionario en el principio del archivo para trabajar. Este archivo generado por Koders no es un archivo 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); 
    } 

El outSize se calcula de la misma manera que su método Compress. Pero ¿cómo calcular el tamaño de salida de lo contrario?

+0

¿Hay alguna excepción? ¿Error de mensajes? – PVitt

+0

me siento un NullReferenceException en 'm_Coders [i] .init();' en Init() de la clase LiteralDecoder – Djax

+0

Hay también un poco más respuestas completas aquí: http://stackoverflow.com/ a/8775927/220904 – Vando

Respuesta

26

Esta pregunta es un poco antigua, pero Google no proporciona una respuesta satisfactoria, así que esto es para aquellos que todavía la buscan. Si observa la carpeta LMZAAlone del SDK, hay un código que comprime y descomprime archivos. Usando como ejemplo, parecería que necesita para escribir y leer las propiedades del codificador y descomprime el tamaño de archivo en el archivo de salida:

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

Tenga en cuenta que los archivos creados de esta manera pueden ser extraídos por el programa 7zip también, pero no conservará su nombre de archivo ni ningún otro metadato.

+0

Sé que este es un viejo comentario (y publicación), pero probé este código y no funciona. Al abrir un archivo nuevo, Windows 10 dice que no es válido y no lo abrirá. –

+0

Lo probé con la última versión del programa 7zip y la biblioteca y todavía funciona para mí. ¿Qué quieres decir con que Windows 10 dice que no es válido? ¿Estás tratando de abrir el archivo con el visor de archivos comprimidos integrado en el Explorador de Windows? No creo que sea compatible con 7zip/LZMA. – Fr33dan

+0

Resulta que el visualizador de archivos de Windows 10 no es compatible con .7z. Su código funciona, sin embargo, al extraer el archivo archivado, la extensión del archivo no parece estar presente, aunque esté incluida en la cadena de entrada. El archivo sigue siendo válido, solo falta la extensión; ¿Cómo puedes corregir esto? –

Cuestiones relacionadas