Question

J'essaie de décompresser par programmation un fichier compressé.

J'ai essayé d'utiliser la classe System.IO.Compression.GZipStream dans .NET, mais lorsque mon application est exécutée (en réalité un test unitaire), j'obtiens cette exception:

  

System.IO.InvalidDataException: le nombre magique dans l'en-tête GZip n'est pas correct. Assurez-vous de passer dans un flux GZip.

Je réalise maintenant qu'un fichier .zip n'est pas identique à un fichier .gz et que GZip n'est pas identique à Zip .

Cependant, comme je peux extraire le fichier en double-cliquant manuellement sur le fichier zippé, puis en cliquant sur le bouton "Extraire tous les fichiers", je pense qu'il devrait également être possible de le faire dans le code.

J'ai donc essayé d'utiliser Process.Start () avec le chemin d'accès au fichier compressé en tant qu'entrée. Cela amène mon application à ouvrir une fenêtre affichant le contenu du fichier compressé. Tout va bien, mais l’application sera installée sur un serveur avec aucun moyen de cliquer sur le bouton "Extraire tous les fichiers".

Alors, comment puis-je obtenir mon application pour extraire les fichiers dans les fichiers compressés?

Ou y a-t-il un autre moyen de le faire? Je préfère le faire en code, sans télécharger aucune bibliothèque ou application tierce; le service de sécurité n’a pas trop envie de ça ...

Était-ce utile?

La solution

Nous avons utilisé SharpZipLib pour de nombreux projets. Je sais que c’est un outil tiers, mais le code source est inclus et pourrait vous éclairer si vous décidiez de réinventer la roue.

Autres conseils

Avec .NET 4.5 , vous pouvez maintenant décompresser des fichiers à l'aide du framework .NET:

using System;
using System.IO;

namespace ConsoleApplication
{
  class Program
  {
    static void Main(string[] args)
    {
      string startPath = @"c:\example\start";
      string zipPath = @"c:\example\result.zip";
      string extractPath = @"c:\example\extract";

      System.IO.Compression.ZipFile.CreateFromDirectory(startPath, zipPath);
      System.IO.Compression.ZipFile.ExtractToDirectory(zipPath, extractPath);
    }
  }
}

Le code ci-dessus provient directement de la documentation de Microsoft: http: // msdn.microsoft.com/en-us/library/ms404280(v=vs.110).aspx

ZipFile est contenu dans l'assembly System.IO.Compression.FileSystem . (Merci Nateirvin ... voir le commentaire ci-dessous)

Pour .Net 4.5 +

Il n'est pas toujours souhaitable d'écrire le fichier non compressé sur le disque. En tant que développeur ASP.Net, je devrais manipuler les autorisations pour accorder des droits à mon application pour écrire dans le système de fichiers. En travaillant avec des flux en mémoire, je peux éviter tout cela et lire les fichiers directement:

using (ZipArchive archive = new ZipArchive(postedZipStream))
{
    foreach (ZipArchiveEntry entry in archive.Entries)
    {
         var stream = entry.Open();
         //Do awesome stream stuff!!
    }
}

Vous pouvez également écrire le fichier décompressé sur le disque en appelant ExtractToFile () :

.
using (ZipArchive archive = ZipFile.OpenRead(pathToZip))
{
    foreach (ZipArchiveEntry entry in archive.Entries)
    {
        entry.ExtractToFile(Path.Combine(destination, entry.FullName));
    }
} 

Pour utiliser la classe ZipArchive , vous devez ajouter une référence à l'espace de noms System.IO.Compression et à System.IO.Compression.FileSystem. .

Gratuit et aucun fichier DLL externe. Tout est dans un fichier CS. Un téléchargement n'est que le fichier CS, un autre est un exemple très facile à comprendre. Juste essayé aujourd'hui et je ne peux pas croire à quel point la configuration était simple. Cela a fonctionné au premier essai, pas d’erreurs, pas de rien.

https://github.com/jaime-olivares/zipstorer

Utilisez la bibliothèque DotNetZip à l'adresse http://www.codeplex.com/DotNetZip

.
  

bibliothèque de classes et jeu d'outils permettant de manipuler des fichiers zip. Utilisez VB, C # ou n’importe quel langage .NET pour créer, extraire ou mettre à jour facilement des fichiers zip ...

     

DotNetZip fonctionne sur les PC dotés de la totalité du .NET Framework et s’exécute également sur les appareils mobiles utilisant le .NET Compact Framework. Créez et lisez des fichiers zip en VB, C #, ou n’importe quel langage .NET, ou n’importe quel environnement de script ...

     

Si tout ce que vous voulez, c'est une meilleure classe DeflateStream ou GZipStream pour remplacer celle intégrée dans le BCL .NET, DotNetZip l'a également. DeflateStream et GZipStream de DotNetZip sont disponibles dans un assemblage autonome, basé sur un port .NET de Zlib. Ces flux prennent en charge les niveaux de compression et offrent des performances bien meilleures que celles des classes intégrées. Il existe également un flux ZlibStream pour compléter l'ensemble (RFC 1950, 1951, 1952) ...

String ZipPath = @"c:\my\data.zip";
String extractPath = @"d:\\myunzips";
ZipFile.ExtractToDirectory(ZipPath, extractPath);

Pour utiliser la classe ZipFile, vous devez ajouter une référence à l'assembly System.IO.Compression.FileSystem de votre projet

.

Les fichiers zip standard utilisent normalement l'algorithme deflate.

Pour extraire des fichiers sans utiliser de bibliothèques tierces, utilisez DeflateStream. Vous aurez besoin d'un peu plus d'informations sur le format d'archive de fichier zip car Microsoft ne fournit que l'algorithme de compression.

Vous pouvez également essayer d’utiliser zipfldr.dll. Il s'agit de la bibliothèque de compression de Microsoft (dossiers compressés du menu Envoyer à). Il semble que ce soit une bibliothèque mais ce n'est pas documenté. Vous pourrez peut-être le faire fonctionner pour vous grâce à l'expérimentation.

De ici :

  

Objets GZipStream compressés écrits   dans un fichier avec une extension .gz peut   être décompressé en utilisant beaucoup de commun   outils de compression; cependant, cette classe   ne fournit pas en soi   fonctionnalité pour ajouter des fichiers à ou   extraire des fichiers d’archives .zip.

J'utilise ceci pour compresser ou décompresser plusieurs fichiers. Le contenu Regex n’est pas obligatoire, mais je l’utilise pour modifier l’horodatage et supprimer les traits de soulignement indésirables. J'utilise la chaîne vide dans Compresser > & > zipPath Chaîne pour ajouter un préfixe à tous les fichiers si nécessaire. De plus, je commente habituellement Compress () ou Decompress () en fonction de mes activités.

using System;
using System.IO.Compression;
using System.IO;
using System.Text.RegularExpressions;

namespace ZipAndUnzip
{
    class Program
    {
        static void Main(string[] args)
        {
            var directoryPath = new DirectoryInfo(@"C:\your_path\");

            Compress(directoryPath);
            Decompress(directoryPath);
        }

        public static void Compress(DirectoryInfo directoryPath)
        {
            foreach (DirectoryInfo directory in directoryPath.GetDirectories())
            {
                var path = directoryPath.FullName;
                var newArchiveName = Regex.Replace(directory.Name, "[0-9]{8}", "20130913");
                newArchiveName = Regex.Replace(newArchiveName, "[_]+", "_");
                string startPath = path + directory.Name;
                string zipPath = path + "" + newArchiveName + ".zip";

                ZipFile.CreateFromDirectory(startPath, zipPath);
            }

        }

        public static void Decompress(DirectoryInfo directoryPath)
        {
            foreach (FileInfo file in directoryPath.GetFiles())
            {
                var path = directoryPath.FullName;
                string zipPath = path + file.Name;
                string extractPath = Regex.Replace(path + file.Name, ".zip", "");

                ZipFile.ExtractToDirectory(zipPath, extractPath);
            }
        }


    }
}

Vous pouvez tout faire dans .NET 3.5 avec DeflateStream. Ce qui manque dans .NET 3.5, c'est la possibilité de traiter les sections d'en-tête de fichier utilisées pour organiser les fichiers compressés. PKWare a publié ces informations, que vous pouvez utiliser pour traiter le fichier zip après avoir créé les structures utilisées. Ce n'est pas particulièrement onéreux et c'est une bonne pratique de créer des outils sans utiliser de code tiers.

Ce n’est pas une réponse sur une ligne, mais c’est tout à fait faisable si vous voulez et pouvez prendre le temps vous-même. J'ai écrit un cours pour le faire en quelques heures. Ce que j'ai obtenu de cette fonction est la possibilité de compresser et de décompresser des fichiers à l'aide de .NET 3.5 uniquement.

Cela le fera System.IO.Compression.ZipFile.ExtractToDirectory (ZipName, ExtractToPath)

J'ai découvert celui-ci (le package de décompression sur NuGet) aujourd'hui, car j'ai rencontré un problème bug dans DotNetZip, et j’ai réalisé que rien n’avait été fait sur DotNetZip au cours des deux dernières années.

Le paquet Unzip est maigre et il a fonctionné à ma place - il n’avait pas le bogue de DotNetZip. En outre, il s’agissait d’un fichier relativement petit, reposant sur la BCL de Microsoft pour la décompression réelle. Je pouvais facilement faire les ajustements dont j'avais besoin (pour pouvoir suivre les progrès tout en décompressant). Je le recommande.

À partir de ressources intégrées:

using (Stream _pluginZipResourceStream = Assembly.GetExecutingAssembly().GetManifestResourceStream(programName + "." + "filename.zip"))
{
    using (ZipArchive zip = new ZipArchive(_pluginZipResourceStream))
    {
        zip.ExtractToDirectory(Application.StartupPath);
    }
}

Jusqu'à présent, j'utilisais les processus cmd afin d'extraire un fichier .iso, de le copier dans un chemin temporaire du serveur et de l'extraire sur une clé USB. Récemment, j'ai constaté que cela fonctionnait parfaitement avec les .iso de moins de 10 Go. Pour une iso telle que 29Go, cette méthode reste bloquée.

    public void ExtractArchive()
    {
        try
        {

            try
            {
                Directory.Delete(copyISOLocation.OutputPath, true); 
            }
            catch (Exception e) when (e is IOException || e is UnauthorizedAccessException)
            {
            }

            Process cmd = new Process();
            cmd.StartInfo.FileName = "cmd.exe";
            cmd.StartInfo.RedirectStandardInput = true;
            cmd.StartInfo.RedirectStandardOutput = true;
            cmd.StartInfo.CreateNoWindow = true;
            cmd.StartInfo.UseShellExecute = false;
            cmd.StartInfo.WindowStyle = ProcessWindowStyle.Normal;

            //stackoverflow
            cmd.StartInfo.Arguments = "-R";

            cmd.Disposed += (sender, args) => {
                Console.WriteLine("CMD Process disposed");
            };
            cmd.Exited += (sender, args) => {
                Console.WriteLine("CMD Process exited");
            };
            cmd.ErrorDataReceived += (sender, args) => {
                Console.WriteLine("CMD Process error data received");
                Console.WriteLine(args.Data);
            };
            cmd.OutputDataReceived += (sender, args) => {
                Console.WriteLine("CMD Process Output data received");
                Console.WriteLine(args.Data);
            };

            //stackoverflow


            cmd.Start();

            cmd.StandardInput.WriteLine("C:");
            //Console.WriteLine(cmd.StandardOutput.Read());
            cmd.StandardInput.Flush();

            cmd.StandardInput.WriteLine("cd C:\\\"Program Files (x86)\"\\7-Zip\\");
            //Console.WriteLine(cmd.StandardOutput.ReadToEnd());
            cmd.StandardInput.Flush();

            cmd.StandardInput.WriteLine(string.Format("7z.exe x -o{0} {1}", copyISOLocation.OutputPath, copyISOLocation.TempIsoPath));
            //Console.WriteLine(cmd.StandardOutput.ReadToEnd());
            cmd.StandardInput.Flush();
            cmd.StandardInput.Close();
            cmd.WaitForExit();
            Console.WriteLine(cmd.StandardOutput.ReadToEnd());
            Console.WriteLine(cmd.StandardError.ReadToEnd());

vous pouvez utiliser Info-unzip en ligne de commande. Vous n'avez qu'à télécharger unzip.exe à partir du site Web officiel d'Info-unzip.

 internal static void Unzip(string sorcefile)
    {
        try
        {
            AFolderFiles.AFolderFilesDelete.DeleteFolder(TempBackupFolder); // delete old folder   
            AFolderFiles.AFolderFilesCreate.CreateIfNotExist(TempBackupFolder); // delete old folder   
           //need to Command command also to export attributes to a excel file
            System.Diagnostics.Process process = new System.Diagnostics.Process();
            System.Diagnostics.ProcessStartInfo startInfo = new System.Diagnostics.ProcessStartInfo();
            startInfo.WindowStyle = System.Diagnostics.ProcessWindowStyle.Hidden; // window type
            startInfo.FileName = UnzipExe;
            startInfo.Arguments = sorcefile + " -d " + TempBackupFolder;
            process.StartInfo = startInfo;
            process.Start();
            //string result = process.StandardOutput.ReadToEnd();
            process.WaitForExit();
            process.Dispose();
            process.Close();
        }
        catch (Exception ex){ throw ex; }
    }        
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top