2008-10-08 8 views
19

Je sais qu'il y a libraries out there for working with ZIP files. Et, vous pouvez alternativement use the functionality built into Windows for working ZIP files. Mais, je me demande si quelqu'un a trouvé comment utiliser les outils construits dans l'espace de noms System.IO.Compression dans .NET pour lire/écrire des fichiers ZIP? Ou, n'est-il pas possible d'utiliser uniquement cet espace de noms? MISE À JOUR: J'ai l'impression que quelqu'un commente que l'espace de noms System.IO.Packaging pourrait être utile avec cela aussi. Est-ce que quelqu'un sait exactement comment le faire? MSDN a un example complet http://msdn.microsoft.com/en-us/library/system.io.packaging.zippackage.aspx en utilisant la classe ZipPackageComment utiliser System.IO.Compression pour lire/écrire des fichiers ZIP?

Répondre

15

Nécessite .NET 3.5.

+5

En fait, l'espace de noms 'System.IO.Packaging' contient des classes pour travailler avec des packages de style Open Packaging. Vous pouvez l'utiliser pour créer des fichiers ZIP (si vous ne vous souciez pas de certains fichiers supplémentaires qui seront inclus dans votre ZIP), mais il ne peut pas être utilisé pour ouvrir * tout * fichier zip. Voir [bas de la documentation de classe de ZipPackage] (http://msdn.microsoft.com/en-us/library/system.io.packaging.zippackage (v = vs.85) .aspx) pour plus d'informations (cette communauté n'est pas présent dans le document .NET 4.0 mais est toujours valide). – larsmoa

0

Oui, je l'ai utilisé dans le passé. J'ai sous-classé DataSet une fois pour prendre en charge persistant dans un fichier (via la méthode ReadXML/WriteXML). En prime, j'ai décidé de lui permettre d'être, éventuellement, compressé si désiré (ceci, comme vous devriez tous le savoir, est extrêmement efficace avec des données textuelles comme XML).

J'utilisé la classe GZipStream (c'était ma compréhension au moment où la DeflateStream était liée seulement GZip sans information d'en-tête, ou quelque — je suis sûr que quelqu'un pourrait me corriger). Il fonctionne tout simplement en se greffant sur un autre flux et ainsi vous utilisez le GZipStream à sa place. Dans mon cas, il était sur un FileStream.

donné une MemoryStream à remplir avec la sortie de myDataSet.WriteXML(), je l'ai fait quelque chose comme ce qui suit:

if (CompressData) 
{ 
    // Write to memory 
    mStream = new MemoryStream(); 
    Save(mStream); 
    mStream.Seek(0, SeekOrigin.Begin); 

    // Filter that through a GZipStream and then to file 
    fStream = new FileStream(Path.Combine(CacheFilePath, FileName + ".gz"), 
          FileMode.OpenOrCreate); 
    zipStream = new GZipStream(fStream, CompressionMode.Compress, true); 

    Pump(mStream, zipStream); 
} 
else 
{ 
    // Write straight to file 
    fStream = new FileStream(Path.Combine(CacheFilePath, FileName), 
          FileMode.OpenOrCreate); 
    Save(fStream); 
} 

Save() et Pump() sont des méthodes simples comme les suivantes:

private void Pump(Stream input, Stream output) 
{ 
    int n; 
    byte[] bytes = new byte[4096]; // 4KiB at a time 

    while ((n = input.Read(bytes, 0, bytes.Length)) != 0) 
    { 
     output.Write(bytes, 0, n); 
    } 
} 

public void Save(Stream stream) 
{ 
    AcceptChanges(); 

    WriteXml(stream, XmlWriteMode.WriteSchema); 
} 
+0

Votre solution ne lit pas ou n'écrit pas au format de fichier ZIP, mais simplement à la compression de dégonflement brut, ou à l'extension simple d'en-tête-pied GZip autour de la compression de dégonflement. –

+0

+ 1 votre réponse ne peut pas créer de fichiers ZIP, mais elle montre comment utiliser System.IO.Compression, ce qui est idéal pour compresser des fichiers dans SSIS où vous êtes limité à .NET 2.0 et il est difficile d'utiliser des bibliothèques externes. – bstoney

6

Vous allez voulez utiliser une bibliothèque tierce, comme http://www.codeplex.com/DotNetZip, plutôt que d'essayer d'utiliser GZipStream ou DeflateStream pour lire un fichier zip.

Les classes *** Stream dans .NET peuvent vous permettre de lire ou d'écrire des flux compressés d'octets. Ces classes ne lisent pas ou n'écrivent pas de fichiers zip. Le fichier zip est une donnée compressée entourée d'une "enveloppe" ou d'un en-tête. Pensez-y comme des métadonnées - cela inclut le nom du fichier, l'horodatage, le CRC et un tas d'autres choses. Les classes ** Stream produisent uniquement le flux de données compressées et ne savent pas comment produire ou consommer les métadonnées, ce qui est décrit dans la spécification de format PKZip gérée par PKWare.

Les bibliothèques tierces comme DotNetZip gèrent les métadonnées dans une archive ZIP. Ils peuvent ou ne peuvent pas utiliser la classe System.IO.Compression.DeflateStream() pour produire le flux compressé d'octets. Dans les versions précédentes, par exemple, DotNetZip utilisait le DeflateStream intégré. À partir de v1.7, DotNetZip inclut son propre DeflateStream qui est plus efficace que celui fourni dans le .NET Framework. Comme avantage supplémentaire, le DeflateStream intégré dans DotNetZip permet à DotNetZip d'être utilisé sur le .NET Compact Framework 2.0, qui manque d'un System.IO.Compression.DeflateStream. (il a été ajouté dans Compact Framework 3.5)

Il y a un bon forum sur le site DotNetZip si vous avez d'autres questions. Exemple de code C#:

try 
    { 
     using (ZipFile zip = new ZipFile()) 
     { 
      zip.AddDirectory(DirectoryToZip); // recurses subdirs 
      zip.Save(Filename); 
     } 
    } 
    catch (System.Exception ex1) 
    { 
     System.Console.Error.WriteLine("exception: " + ex1); 
    } 
0
public static void zIpDatabseFile(string srcPath, string destPath) 
    {//This is for Zip a File 
     using (var source = new FileStream(srcPath, FileMode.Open, FileAccess.Read, FileShare.Read)) 
     using (var dest = new FileStream(destPath, FileMode.OpenOrCreate, FileAccess.Write)) 
     using (var zip = new GZipStream(dest, CompressionMode.Compress)) 
     { 
      source.CopyTo(zip); 
     } 
    } 
    public static void uNzIpDatabaseFile(string SrcPath, string DestPath) 
    {// This is for unzip a files. 
     using (var source = new FileStream(SrcPath, FileMode.Open, FileAccess.Read, FileShare.Read)) 
     using (var dest = new FileStream(DestPath, FileMode.OpenOrCreate, FileAccess.Write)) 
     using (var zip = new GZipStream(source, CompressionMode.Decompress)) 
     { 
      zip.CopyTo(dest); 
     } 
    } 
5

Depuis .NET 4.5, Microsoft a offert la classe ZipArchive à l'espace de noms System.IO.Compression. Contrairement à d'autres classes dans cet espace de noms, cependant, comme GZipStream et Deflate flux, le ZipArchivenécessite une référence à l'assembly System.IO.Compression.dll.

Il est assez simple à utiliser, et le lien ci-dessus vers MSDN fournit de bons exemples.

En outre, Microsoft a créé le Microsoft Compression NuGet package, qui ajoute le support pour ZipArchive et classes associées à Windows Phone 8 et d'autres bibliothèques de classe Portable

3

Une discussion plus, je sais, mais je voudrais souligner que. NET 4.5 a ajouté de nombreuses améliorations à system.io.compression. Il peut désormais très bien manipuler les fichiers .zip, jusqu'à exposer des fichiers individuels dans le fichier zip en tant que flux capables de lire ou d'écrire sans avoir à extraire et compresser les fichiers.

Questions connexes