devstory

Compression et décompression dans C#

  1. La hiérarchie des classes
  2. ZipFile
  3. ZipArchive
  4. Annexe: Correction d'erreur

1. La hiérarchie des classes

Ci- dessous sont lq liste des classes qui utilisent pour compresser ou extraire le fichier. Elles se trouvent dans l'espace- nom System.IO.Compression.
Classe
Description
ZipFile
Fournit des méthodes statiques pour créer, extraire et ouvrir des archives zip.
ZipArchive
Représente un paquet de fichiers compressés dans le format d'archive ZIP.
ZipArchiveEntry
Représente un fichier compressé dans une archive ZIP.
DeflateStream
Fournit des méthodes et des propriétés pour compresser et décompresser des flux à l'aide de l'algorithme Deflate.
GZipStream
Fournit des méthodes et des propriétés utilisées pour compresser et décompresser les flux (stream).
Notez que cette classe est introduite dans C# à partir de la version 4.5, donc votre projet doit utiliser .NET avec la version 4.5 ou la version plus avancée.

2. ZipFile

La classe ZipFile est une classe d'utilitaire. Elle comprend plusieurs méthodes statiques qui vous aide d'ouvrir le fichier zip, d'extraire des données, ou dans la situation où un répertoire est compressé dans un fichier zip, d'extraire le fichier zip dans un dossier, ..
Le simple exemple ci- dessous utilise la méthode de la classe ZipFile pour compresser un fichier dans un fichier zip et après d'extraire ce fichier à un fichier nouveau.
ZipDirectoryDemo.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.IO.Compression;

namespace CompressionTutorial
{
    class ZipDirectoryDemo
    {
        public static void Main(string[] args)
        {
            // Le dossier sera compressé.
            string inputDir = "C:/test/inputdir";

            // Le fichier de sortie après avoir compressé le dossier ci-dessus.
            string zipPath = "C:/test/data.zip";

            // Décompressez le fichier zip dans le dossier.
            string extractPath = "C:/test/outputdir";

            // Créez un fichier zip en compressant un dossier.
            ZipFile.CreateFromDirectory(inputDir, zipPath);

            // Décompressez le fichier zip dans le dossier.
            ZipFile.ExtractToDirectory(zipPath, extractPath);

            Console.WriteLine("Done!");
        }
    } 
}
Si vous recevez un message d'erreur: "The name 'ZipFile' does not exist in the current context"(Malgré que vous avez déclaré using System.IO.Compression) ça signifie que votre projet utilise l'ancien .NET 4.5 ou le programme ne trouve pas la bibliothèuque DLL. Vous pouvez voir comment fixer cet erreur dans l'annexe à la fin de ce document.
Exécutez l'exemple et recevez les résultats:
  • data.zip

3. ZipArchive

ZipArchive représente un ensemble de fichiers qui sont compressés dans un fichier sous format ZIP. Vous pouvez créer l'objet ZipArchive à travers la méthode OpenRead de classe ZipFile. Via ZipArchive vous pouvez lire les sous- fichiers qui sont compressés dans le fichier zip.
L'exemple ci- dessous énumère des fichiers ZipArchiveEntry qui ont compris dans le fichier zip.
ListArchiveEntryDemo.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.IO.Compression;
using System.IO; 

namespace CompressionTutorial
{
    class ListArchiveEntryDemo
    { 
        public static void Main(string[] args)
        {
            string zipPath =  "c:/test/data.zip";  
            using (ZipArchive archive = ZipFile.OpenRead(zipPath))
            {
                // Récupérez la liste des ZipArchiveEntry.
                foreach (ZipArchiveEntry entry in archive.Entries)
                {
                    Console.WriteLine("Entry:");
                    Console.WriteLine("  Name = " + entry.Name);
                    Console.WriteLine("  FullName = " + entry.FullName);
                }
            } 
            Console.Read();
        }
    } 
}
Exécution l'exemple:
Entry:
  Name = data.docx
  FullName = data.docx
Entry:
  Name = image.bmp
  FullName = image.bmp
Entry:
  Name = readme.txt
  FullName = readme.txt
Entry:
  Name = Dotnet.docx
  FullName = documents\Dotnet.docx
Entry:
  Name = java.docx
  FullName = documents\java.docx
Extrayez des fichiers des données dans le fichier zip:
ExtractDemo.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.IO.Compression;
using System.IO;

namespace CompressionTutorial
{
    class ExtractDemo {
        static void Main(string[] args)
        {
            string zipPath = "c:/test/data.zip"; 
            // Le répertoire de sortie pour décompresser.
            string extractPath = "c:/test/extract";

            // S'il n'existe pas, créez-le.
            if (!Directory.Exists(extractPath))
            {
                System.IO.Directory.CreateDirectory(extractPath);
            } 
            using (ZipArchive archive = ZipFile.OpenRead(zipPath))
            {
                foreach (ZipArchiveEntry entry in archive.Entries)
                {
                    Console.WriteLine("Found: " + entry.FullName); 
                    // Trouvez les entrées se termine par .docx
                    if (entry.FullName.EndsWith(".docx", StringComparison.OrdinalIgnoreCase))
                    {
                        // Par exemple : documents/Dotnet.docx
                        Console.WriteLine(" - Extract entry: " + entry.FullName);

                        // C:/test/extract/documents/Dotnet.docx  ...
                        string entryOuputPath = Path.Combine(extractPath, entry.FullName); 
                        Console.WriteLine(" - Entry Ouput Path: " + entryOuputPath);

                        FileInfo fileInfo = new FileInfo(entryOuputPath); 
                        // Assurez-vous que le répertoire contenant ce fichier existe.
                        // à savoir : C:/test/extract/documents
                        fileInfo.Directory.Create();

                        // Remplacez l'ancien fichier s'il existe déjà.
                        entry.ExtractToFile(entryOuputPath,true);
                    }
                }
            } 
            Console.ReadLine();
        }
    } 
}
Exécutez l'exemple:
Found: data.docx
 - Extract entry: data.docx
 - Entry Output Path: c:/test/extract\data.docx
Found: image.bmp
Found: readme.txt
Found: documents\Dotnet.docx
 - Extract entry: documents\Dotnet.docx
 - Entry Output Path: c:/test/extract\documents\Dotnet.docx
Found: documents\java.docx
 - Extract entry: documents\java.docx
 - Entry Output Path: c:/test/extract\documents\java.docx
Vous pouvez mettre les fichiers dans un fichier zip disponible.
AddEntryDemo.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.IO.Compression;
using System.IO;

namespace CompressionTutorial
{
    class AddEntryDemo
    {
        static void Main(string[] args)
        {
            string zipPath = "C:/test/data.zip";

            // Ouvrir le flux (stream) pour lire le fichier zip.
            using (FileStream zipStream = new FileStream(zipPath, FileMode.Open))
            {
                // Créez l'objet ZipArchive.
                using (ZipArchive archive = new ZipArchive(zipStream, ZipArchiveMode.Update))
                {
                    // Ajoutez une entrée au ZipArchive.
                    ZipArchiveEntry readmeEntry = archive.CreateEntry("note/Note.txt");

                    // Créez un flux pour écrire du contenu à l'entrée.
                    using (StreamWriter writer = new StreamWriter(readmeEntry.Open()))
                    {
                        writer.WriteLine("## Note.txt");
                        writer.WriteLine("========================");
                    }
                }
            }
        }
    } 
}
Exécutez l'exemple et recevez des résultats.

4. Annexe: Correction d'erreur

Si vous obtenez un message d'erreur: "The name 'ZipFile' does not exist in the current context" (Bien que vous avez déclaré d'utiliser System.IO.Compression), ce qui signifie que votre projet utilisant l'ancien .NET 4.5 ou le programme ne trouve pas la bibliothèque DLL nécessaire.
Cliquez sur le bouton droit du Projet, sélectionnez Properties, assurez vous que votre projet utilise la version .NET Framework 4.5 ou la version plus avancée.
Réexécutez votre classe et voir si l'interprète n'a des erreurs ou pas. Au cas où il y a encore des notifications des erreurs, vous devez désigner la location de la bibliothèque DLL.
  • C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.5\System.IO.Compression.FileSystem.dll
  • C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.5.1\System.IO.Compression.FileSystem.dll
Cliquez sur le bouton droit du Projet et sélectionnez:
  • Add/Reference..
Sélectionnez le fichier:
  • System.IO.Compression.FileSystem.dll
De la même façon, si vous recevez la notification "The name 'ZipArchive' does not exist in the current context" (Même si vous avez déclaré using System.IO.Compression) vous devez déclarer l'utilisation de la bibliothèque System.IO.Compression.dll:
De la même façon, si vous recevez la notification "The name 'Path' does not exist in the current context" (Malgré que vous avez déclaré using System.IO) vous devez déclarer l'utilisation de la bibliothèque mscorlib.dll: