web-dev-qa-db-fra.com

Comment créer des archives 7-Zip avec .NET?

Comment créer des archives 7-Zip à partir de mon application console C #? Je dois pouvoir extraire les archives en utilisant le programme régulier et largement disponible 7-Zip .


Voici mes résultats avec les exemples fournis comme réponses à cette question

  • "Transmettre" à 7z.exe - c'est l'approche la plus simple et la plus efficace, et je peux confirmer que cela fonctionne bien. Comme workmad3 mentionne , je dois simplement garantir que 7z.exe est installé sur toutes les machines cibles, ce que je peux garantir.
  • 7 compression ZIP en mémoire - il s'agit de la compression des cookies "en mémoire" avant l'envoi au client; cette méthode semble quelque peu prometteuse. Les méthodes d'encapsulation (enveloppant le LZMA SDK ) renvoient le type byte[]. Lorsque j'écris le tableau byte[] dans un fichier, je ne peux pas l'extraire à l'aide de 7-Zip (File.7z is not supported archive).
  • 7zSharp Wrapper (trouvé sur CodePlex) - cela enveloppe le 7z exe/ LZMA SDK . J'ai référencé le projet à partir de mon application et il a réussi à créer des fichiers archive, mais je n'ai pas pu extraire les fichiers à l'aide du programme 7-Zip standard (File.7z is not supported archive).
  • 7Zip SDK, alias LZMA SDK - Je suppose que je ne suis pas assez intelligent pour comprendre comment l'utiliser (c'est pourquoi j'ai posté ici) ... Tous les exemples de code de travail illustrant la création d'une archive 7Zip capable de être extrait par le programme régulier 7Zip?
  • Interface CodeProject C # (.NET) pour les DLL d'archivage 7-Zip - ne prend en charge que l'extraction à partir d'archives 7Zip ... J'ai besoin de les créer!
  • SharpZipLib - Selon leur FAQ , SharpZipLib ne prend pas en charge 7Zip.
92
Seibar

Si vous pouvez garantir que l'application 7-Zip sera installée (et dans le chemin) sur toutes les machines cibles, vous pouvez effectuer un déchargement en appelant l'application de ligne de commande 7z. Pas la solution la plus élégante mais c'est le moins de travail. 

28
workmad3

Exemple de cookie EggCafe 7Zip Ceci est un exemple (cookie zippé) avec le DLL de 7Zip.

CodePlex Wrapper .__ Ceci est un projet open source qui déforme la fonction de zipping de 7z.

SDK 7Zip Le SDK officiel de 7Zip (C, C++, C #, Java) <--- Ma suggestion

Bibliothèque .Net Zip de SharpDevelop.net

CodeProject exemple avec 7Zip

SharpZipLib Nombreuses compressions

74
Patrick Desjardins

SevenZipSharp est une autre solution. Crée des archives 7-Zip ...

25
markhor

Voici un exemple de travail complet utilisant le SDK SevenZip en C #. 

Il écrira et lira les fichiers 7Zip standard créés par l’application Windows 7Zip. 

PS. L'exemple précédent ne va jamais décompresser car il n'a jamais écrit les informations de propriété requises au début du fichier.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using SevenZip.Compression.LZMA;
using System.IO;
using SevenZip;

namespace VHD_Director
{
    class My7Zip
    {
        public static void CompressFileLZMA(string inFile, string outFile)
        {
            Int32 dictionary = 1 << 23;
            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";
            bool eos = true;
            bool stdInMode = false;


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

            using (FileStream inStream = new FileStream(inFile, FileMode.Open))
            {
                using (FileStream outStream = new FileStream(outFile, FileMode.Create))
                {
                    SevenZip.Compression.LZMA.Encoder encoder = new SevenZip.Compression.LZMA.Encoder();
                    encoder.SetCoderProperties(propIDs, properties);
                    encoder.WriteCoderProperties(outStream);
                    Int64 fileSize;
                    if (eos || stdInMode)
                        fileSize = -1;
                    else
                        fileSize = inStream.Length;
                    for (int i = 0; i < 8; i++)
                        outStream.WriteByte((Byte)(fileSize >> (8 * i)));
                    encoder.Code(inStream, outStream, -1, -1, null);
                }
            }

        }

        public static void DecompressFileLZMA(string inFile, string outFile)
        {
            using (FileStream input = new FileStream(inFile, FileMode.Open))
            {
                using (FileStream output = new FileStream(outFile, FileMode.Create))
                {
                    SevenZip.Compression.LZMA.Decoder decoder = new SevenZip.Compression.LZMA.Decoder();

                    byte[] properties = new byte[5];
                    if (input.Read(properties, 0, 5) != 5)
                        throw (new Exception("input .lzma is too short"));
                    decoder.SetDecoderProperties(properties);

                    long outSize = 0;
                    for (int i = 0; i < 8; i++)
                    {
                        int v = input.ReadByte();
                        if (v < 0)
                            throw (new Exception("Can't Read 1"));
                        outSize |= ((long)(byte)v) << (8 * i);
                    }
                    long compressedSize = input.Length - input.Position;

                    decoder.Code(input, output, compressedSize, outSize, null);
                }
            }
        }

        public static void Test()
        {
            CompressFileLZMA("DiscUtils.pdb", "DiscUtils.pdb.7z");
            DecompressFileLZMA("DiscUtils.pdb.7z", "DiscUtils.pdb2");
        }
    }
}
22
Orwellophile

J'ai utilisé le SDK. 

par exemple:

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();
      }
   }
}
8
WOPR
 string zipfile = @"E:\Folderx\NPPES.Zip";
 string folder = @"E:\TargetFolderx";

 ExtractFile(zipfile,folder);
public void ExtractFile(string source, string destination)
        {
            // If the directory doesn't exist, create it.
            if (!Directory.Exists(destination))
                Directory.CreateDirectory(destination);

            //string zPath = ConfigurationManager.AppSettings["FileExtactorEXE"];
          //  string zPath = Properties.Settings.Default.FileExtactorEXE; ;

            string zPath=@"C:\Program Files\7-Zip\7zG.exe";

            try
            {
                ProcessStartInfo pro = new ProcessStartInfo();
                pro.WindowStyle = ProcessWindowStyle.Hidden;
                pro.FileName = zPath;
                pro.Arguments = "x \"" + source + "\" -o" + destination;
                Process x = Process.Start(pro);
                x.WaitForExit();
            }
            catch (System.Exception Ex) { }
        }

Il suffit d’installer 7 Zip à partir de la source et de transmettre le paramètre à la méthode.

Merci. S'il vous plaît, aimez la réponse.

3
Vishal sen

Ce moyen le plus simple est de travailler avec des fichiers .Zip au lieu de .7z et d’utiliser Dot Net Zip

Lors du transfert de commandes 7Zip à Shell, il existe d'autres problèmes, tels que les privilèges utilisateur, un problème avec SevenZipSharp.

Private Function CompressFile(filename As String) As Boolean
Using Zip As New ZipFile()
    Zip.AddFile(filename & ".txt", "")
    Zip.Save(filename & ".Zip")
End Using

Return File.Exists(filename & ".Zip")
End Function
1
Brent

J'utilise ce code 

                string PZipPath = @"C:\Program Files\7-Zip\7z.exe";
                string sourceCompressDir = @"C:\Test";
                string targetCompressName = @"C:\Test\abc.Zip";
                string CompressName = targetCompressName.Split('\\').Last();
                string[] fileCompressList = Directory.GetFiles(sourceCompressDir, "*.*");

                    if (fileCompressList.Length == 0)
                    {
                        MessageBox.Show("No file in directory", "Important Message");
                        return;
                    }
                    string filetozip = null;
                    foreach (string filename in fileCompressList)
                    {
                        filetozip = filetozip + "\"" + filename + " ";
                    }

                    ProcessStartInfo pCompress = new ProcessStartInfo();
                    pCompress.FileName = PZipPath;
                    if (chkRequestPWD.Checked == true)
                    {
                        pCompress.Arguments = "a -tzip \"" + targetCompressName + "\" " + filetozip + " -mx=9" + " -p" + tbPassword.Text;
                    }
                    else
                    {
                        pCompress.Arguments = "a -tzip \"" + targetCompressName + "\" \"" + filetozip + "\" -mx=9";
                    }
                    pCompress.WindowStyle = ProcessWindowStyle.Hidden;
                    Process x = Process.Start(pCompress);
                    x.WaitForExit();
1
lifestylebyatom

SharpCompress est à mon avis l’une des bibliothèques de compression les plus intelligentes du marché. Il prend en charge LZMA (7-Zip), est facile à utiliser et en développement actif.

Comme il prend déjà en charge le streaming LZMA, il ne supporte malheureusement, à l’heure de la rédaction, que la lecture des archives 7-Zip. MAIS l'écriture d'archive est sur leur liste de tâches (voir le readme). Pour les futurs lecteurs: Cochez pour obtenir le statut actuel ici: https://github.com/adamhathcock/sharpcompress/blob/master/FORMATS.md

0
Mario Eis

Quelques informations de test supplémentaires sur le code @Orwellophile à l’aide d’un fichier texte de 17,9 Mo.
L'utilisation des valeurs de propriété dans l'exemple de code "tel quel" aura un impact négatif ÉNORANT sur les performances, cela prend 14,16 secondes .

Définissez les propriétés suivantes comme suit: 3,91 sec (entre autres, l’archive contiendra les mêmes informations sur le conteneur: vous pouvez extraire et tester le archive avec 7Zip mais il n'y a pas d'information de nom de fichier)

7Zip natif 2 secondes

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

J'ai fait un autre test en utilisant 7Zip natif et un fichier de sauvegarde SQL de 1,2 Go (.bak)
7Zip (compression maximale): 1 minute
LZMA SDK (@Orwellophile avec la configuration de propriété ci-dessus): 12:26 min :
Fichier de sortie à peu près de la même taille.

Je suppose donc que j'utiliserai moi-même une solution basée sur le moteur c/c ++, i.a. soit appeler l'exécutable 7Zip à partir de c # ou utiliser --- (squid-box/SevenZipSharp , qui encapsule le fichier dll 7Zip c/c ++ et semble être le dernier fork de SevenZipSharp. Je n'ai pas testé l'emballage, mais j'espère que c'est aussi performant que le 7Zip natif. Mais j'espère que cela donnera la possibilité de compresser le flux, ce que vous ne pouvez évidemment pas faire si vous appelez directement l'exe. Sinon, je suppose qu’il n’ya aucun avantage à appeler l’exe. Le wrapper a quelques dépendances supplémentaires donc il ne rendra pas votre projet publié "plus propre".

En passant, il semble que l’équipe .Net Core envisage d’implémenter LZMA dans la classe system.io dans .Core ver. 5, ce serait génial!

(Je sais que c'est en quelque sorte un commentaire et non une réponse, mais pour pouvoir fournir l'extrait de code, il ne peut s'agir d'un commentaire)

0
MrCalvin

Installez le paquet NuGet appelé SevenZipSharp.Interop

Ensuite:

SevenZipBase.SetLibraryPath(@".\x86\7z.dll");
var compressor = new SevenZip.SevenZipCompressor();
var filesToCompress = Directory.GetFiles(@"D:\data\");
compressor.CompressFiles(@"C:\archive\abc.7z", filesToCompress);
0
Fidel