Le framework .NET offre beaucoup de fonctionnalités aux développeurs afin d’éviter à avoir à écrire et réécrire certaines fonctionnalités avec le temps. Un domaine qui a toujours manqué à .NET à travers le temps est au niveau de la compression de fichiers.
Sans avoir recours à une librairie externe, il y a les deux choix qui s’offraient au développeur :
Le tout est bien et assez fonctionnel. Dans les deux cas, il est possible de prendre un fichier en mémoire et de le compresser pour ainsi économiser en espace lors du transport.
J’ai toujours trouvé l’opération assez fastidieuse et très répétitive. Sommairement, compresser un fichier équivalait à :
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
namespace Compression | |
{ | |
public class Compression | |
{ | |
public static void Compress(FileInfo fi) | |
{ | |
using (FileStream inFile = fi.OpenRead()) | |
{ | |
if ((File.GetAttributes(fi.FullName) & FileAttributes.Hidden) != FileAttributes.Hidden & fi.Extension != ".gz") | |
{ | |
using (FileStream outFile = File.Create(fi.FullName + ".gz")) | |
{ | |
using (GZipStream Compress = new GZipStream(outFile, CompressionMode.Compress)) | |
{ | |
inFile.CopyTo(Compress); | |
} | |
} | |
} | |
} | |
} | |
} | |
} |
Prenez note que j’ai laissé la mention du Namespace pour avoir encore plus une plus belle pyramide de code!
Le vrai problème est que l’algorithme Deflate est utilisé pour les fichiers Zip mais la classe DeflateStream ne fournit pas les entêtes de fichiers nécessaires pour la création de fichiers Zip. Cela n’est pas très pratique.
L’alternative à tout ça aura été la librairie DotNetZip. Cette librairie a été le choix de-facto afin de compresser des fichiers dans le format Zip. Le résultat est à la hauteur sans artifices et à la hauteur des attentes :
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using (ZipFile zip = new ZipFile()) | |
{ | |
zip.AddFile("c:\\images\\personal\\7440-N49th.png", "images"); | |
zip.AddFile("c:\\Reports\\2008-Regional-Sales-Report.pdf", "files"); | |
zip.AddFile("ReadMe.txt"); | |
zip.Save("MyZipFile.zip"); | |
} |
La nouveauté
Avec .NET 4.5, cette époque est révolue. La gestion de fichier archives .NET est maintenant intégrée directement dans le Framework sous le namespace System.IO.Compression.
Au total, il y a quatre classes vous permettant de faire la gestion de vos archives. À chacune son rôle bien spécifique :
- ZipFile
- Offre les méthodes nécessaires pour la création, extraction et ouverture des fichiers Zip.
- ZipFileExtensions
- Ajoute certaines extensions aux fonctionnalités pour la gestion des archives compressées. Par exemple. il est possible de compresser un répertoire entier ou même d’ajouter des fichiers à une archive Zip existante.
- ZipArchive
- Représente une archive Zip. Le conteneur des fichiers compressés.
- ZipArchiveEntry
- Représente un fichier à l’intérieur d’une archive Zip.
Exemples
La manipulation de l’API est très simple. Il faut reconnaître que l’équipe du développement de .NET a fait du beau travail avec la gestion des archives Zip.
Notez que, dans tous les cas, il est important d’ajouter les références à System.IO.Compression ainsi que System.IO.Compression.FileSystem pour que le tout puisse compiler.
Création
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using (ZipArchive archive = ZipFile.Open(@"c:\frenchcoding\start.zip", ZipArchiveMode.Create)) | |
{ | |
archive.CreateEntryFromFile(@"c:\frenchcoding\test.txt", "test_compress.txt"); | |
archive.CreateEntryFromFile(@"c:\frenchcoding\test2.txt", "test_compress2.txt"); | |
archive.CreateEntryFromFile(@"c:\frenchcoding\test3.txt", "test_compress3.txt"); | |
} |
Extraction
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using (ZipArchive archive = ZipFile.Open(@"c:\frenchcoding\start.zip", ZipArchiveMode.Read)) | |
{ | |
archive.ExtractToDirectory(@"c:\frenchcoding\extract\"); | |
} |
Suppression d’éléments
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using (ZipArchive archive = ZipFile.Open(@"c:\frenchcoding\start.zip", ZipArchiveMode.Update)) | |
{ | |
archive | |
.GetEntry("test_compress2.txt") | |
.Delete(); | |
archive | |
.GetEntry("test_compress3.txt") | |
.Delete(); | |
} |
Oh WOW !
C’est ben cool tout ça !
J’avais déjà utilisé la librairie GZip dans le temps du framework 1.1 pour un vieux projet en vb.net, mais avoir accès aujourd’hui à un utilitaire built-in pour compresser/décompresser en .zip est une fonctionnalité vraiment intéressante!
Bonjour,
Je suis confronté à un souci car je dois zipper plusieurs fichiers. Cette classe m’intéresse mais mes fichiers sont éparpillés sur plusieurs serveurs, donc plusieurs répertoires. Dans chaque répertoires j’ai énormément de données qui ne m’intéresse pas, j’ai besoin que d’un fichier ici et les autres ailleurs.
Merci