2010-09-20 22 views
16

Je voudrais savoir s'il y a un moyen d'éviter d'avoir un [Content_Types] .xml fichier dans le fichier zip en utilisant ZipPackage de .net classe.comment éviter [Content_Types] .xml dans ZipPackage la classe .net

+0

Quelle est la raison d'utiliser 'ZipPackage'? Si vous souhaitez créer un fichier zip à partir de documents existants, il est préférable d'utiliser 'GZipStream' et les classes associées dans l'espace de noms' System.IO.Compression'. – shahkalpesh

+5

@shahkalpesh: GZipStream est réservé aux fichiers uniques. –

+0

@Henk: Je souhaite créer un fichier ".zip" pour un seul document. Est-il possible de créer un fichier ".zip" en utilisant GZipStream? –

Répondre

10

No.

paquets Zip ne sont pas (normal) les fichiers Zip. Ils doivent suivre une structure imposée et contenir ce fichier Content_Types.xml à la racine. ZipPackage = ZipArchive + Structure.

Si vous voulez créer (et surtout si vous voulez lire) des archives Zip normales, vous aurez besoin d'une bibliothèque supplémentaire, il n'y a pas de support dans la BCL.

Voir SharpZipLib (GPL) et DotNetZip

+0

Que faites-vous signifie par "normal"? N'est-il pas possible de créer un fichier ".zip" en utilisant tout ce qui est dans le framework .net? –

+1

@Kushal: Package = Zip Archive + Structure. Donc, vous pouvez lire un paquet Zip avec WinZip, mais vous ne pouvez pas lire (tous) les fichiers Zip avec ZipPackage –

+0

Je souhaite juste compresser un seul fichier. Mais je ne suis pas capable de me débarrasser du fichier .xml qui est incorporé avec le paquet. –

3

Si vous ne l'appelez pas la méthode .Flush(), il n'y aura pas un tel fichier

+0

Ceci est une excellente réponse à cette question, et cette technique a fonctionné pour moi. Si vous créez votre 'ZipPackage' avec un flux de mémoire, ajoutez vos parties, puis copiez le flux avant de disposer du' ZipPackage' (qui appelle '.Flush()') alors le fichier zip résultant contient seulement vos parties ajoutées et non " [Context_Types] .xml ". –

+0

@DLeh Désolé, que voulez-vous dire? C'est exactement la méthode, pour éviter que le fichier ait été ajouté au fichier zip. – Yiping

+0

@MattKlein Merci.J'ai trouvé cela par hasard (j'ai oublié de disposer). Mais cela semble fonctionner. – Yiping

1

Oui, vous pouvez créer des packages zip sans le contenu XML supplémentaire fichier ajouté

Inspiré par ce lien: Using System.IO.Packaging to generate a ZIP file

L'utilisation ci-dessus mentionnée par la découverte Yiping vous pouvez Avoi d le fichier xml supplémentaire ajouté au package. Enregistrer le flux zip du flux de mémoire vers un fichier zip physique avant que l'archive zip ne soit fermée comme ceci:

public static void AddFilesToZip(string zipFilename, List<String> filesToAdd) 
{ 
    using (var memStream = new MemoryStream()) 
    { 
     using (Package zip = System.IO.Packaging.Package.Open(memStream, FileMode.Create)) 
     { 

      foreach (var fileToAdd in filesToAdd) 
      { 
       string destFilename = ".\\" + Path.GetFileName(fileToAdd); 
       Uri uri = PackUriHelper.CreatePartUri(new Uri(destFilename, UriKind.Relative)); 

       //Existing parts not likely in fresh memory stream 
       if (zip.PartExists(uri)) 
       { 
        zip.DeletePart(uri); 
       } 

       PackagePart part = zip.CreatePart(uri, "", CompressionOption.Normal); 

       using (FileStream fileStream = new FileStream(fileToAdd, FileMode.Open, FileAccess.Read)) 
       { 

        using (Stream dest = part.GetStream()) 
        { 
         CopyStream(fileStream, dest); 
        } 
       } 
      } 

      //The zip Package will add an XML content type file to memeory stream when it closes 
      //so before it closes we save the memorystream to physical zip file. 
      using (FileStream zipfilestream = new FileStream(zipFilename, FileMode.Create, FileAccess.Write)) 
      { 
       memStream.Position = 0; 
       CopyStream(memStream, zipfilestream); 
      } 

      //Thats it. Zip file saved to file. Things added by package after this point will be to meory stream finally disposed. 
     } 
    } 
} 
+0

Vous avez ce travail, merci. La partie importante est memStream.Position = 0; sans cela, vous obtiendrez un zip vide. – apc

+1

Où 'CopyStream' vient? J'ai testé votre code, mais quand j'extrais le contenu du .zip, dit que le .zip est endommagé. –

0

Homme, cela m'a beaucoup aidé! Tu gères! Je devais l'utiliser car mon ancien framework (3.5). Seulement pour compléter, voir ci-dessous la mise en œuvre de la fonction CopyStream:

private void CopyStream(Stream source, Stream target) 
    { 
     const int bufSize = 0x1000; 
     byte[] buf = new byte[bufSize]; 
     int bytesRead = 0; 
     while ((bytesRead = source.Read(buf, 0, bufSize)) > 0) 
      target.Write(buf, 0, bytesRead); 
    } 
0

Vous pouvez également définir domaine privé _contentTypeHelper de System.IO.Packaging.Package à null (en utilisant DynamicObject).