2009-06-21 9 views
47

Sieht aus wie keine integrierte Bibliothek/API in C# zum Entpacken einer Zip-Datei. Ich suche nach einer freien (besser Open Source) Bibliothek/API, die mit .Net 3.5 + VSTS 2008 + C# funktionieren könnte, um eine Zip-Datei zu entpacken und alle Dateien in einen bestimmten Ordner zu extrahieren.empfehlen eine Bibliothek/API zum Entpacken der Datei in C#

Beliebige empfohlene Bibliothek/API oder Beispiele?

Antwort

34

Die GPL

http://www.icsharpcode.net/OpenSource/SharpZipLib/

ODER die weniger restriktive Ms-PL

http://www.codeplex.com/DotNetZip

dies das .net Framework beantworten zu vervollständigen hat ZipPackage hatte ich weniger Erfolg damit.

+1

auch. NET hat eine eingebaute Implementierung, aber es ist unmöglich, mit –

+0

Cool zu arbeiten Ich mag die erste. Für die .Net one, welche Klasse meinst du? – George2

+0

Warum meinst du .Net ZipPackage ist weniger Erfolg? – George2

2

Wenn Sie 7-Zip-Komprimierung verwendet werden Besuche EggheadCafe article Peter Bromberg. Vorsicht: Die LZMA source code für C# hat keine XML-Kommentare (eigentlich nur sehr wenige Kommentare).

16

DotNetZip ist einfach zu bedienen. Hier ist ein unzip Probe

using (var zip = Ionic.Zip.ZipFile.Read("archive.zip")) 
{ 
    zip.ExtractAll("unpack-directory"); 
} 

Wenn Sie komplexere Bedürfnisse haben, wie Sie Pick-and-wählen möchten, welche extrahieren Einträge, oder wenn es Passwörter, oder wenn Sie die Pfadnamen der extrahierten Dateien steuern möchten oder etc etc etc, es gibt viele Möglichkeiten. Check the help file für weitere Beispiele.

DotNetZip ist kostenlos und Open Source.

9

In der Vergangenheit habe ich DotNetZip (MS-PL), SharpZipLib (GPL) und die 7ZIP SDK for C# (public domain) verwendet. Sie alle arbeiten großartig und sind Open Source.

Ich würde DotNetZip in dieser Situation wählen, und hier ist ein Beispielcode aus dem C# Examples page:

using (ZipFile zip = ZipFile.Read(ExistingZipFile)) 
{ 
    foreach (ZipEntry e in zip) 
    { 
    e.Extract(TargetDirectory); 
    } 
} 
+1

LGPL, nicht GPL - der Unterschied ist ziemlich groß. –

+0

@Quandary welche? SharpZipLib ist laut ihrer Website GPL. –

+0

GPL mit dieser Ausnahme (Verknüpfung statisch oder dynamisch mit Ihrem Projekt ist keine abgeleitete Arbeit unter der GPL) = LGPL (ok, die Erlaubnis statisch zu verknüpfen ist nicht in der LGPL, deshalb schreiben sie es so, aber statisch verknüpfen ist ungewöhnlich für .NET). Ehrlich gesagt ist es eine liberalere Version der LGPL. –

23

Wenn Sie nur den Inhalt einer Datei in einen Ordner entpacken möchten und Sie wissen, dass Sie nur unter Windows arbeiten, können Sie das Windows Shell-Objekt verwenden. Ich habe dynamic von Framework 4.0 in diesem Beispiel verwendet, aber Sie können die gleichen Ergebnisse mit Type.InvokeMember erreichen.

dynamic shellApplication = Activator.CreateInstance(Type.GetTypeFromProgID("Shell.Application")); 

dynamic compressedFolderContents = shellApplication.NameSpace(sourceFile).Items; 
dynamic destinationFolder = shellApplication.NameSpace(destinationPath); 

destinationFolder.CopyHere(compressedFolderContents); 

können Sie FILEOP_FLAGS verwenden Verhalten der CopyHere Methode zu steuern.

+1

Mit Abstand die tollste Antwort auf diese uralte Frage! Dies bedarf einer größeren Aufwertung. – Joshua

+1

Ich muss @joshuam zustimmen ... – dda

1

Wenn Sie keine externe Komponente verwenden möchten, hier ist ein Code, den ich letzte Nacht mit der ZipPackage-Klasse von .NET entwickelt habe.

private static void Unzip() 
{ 
    var zipFilePath = "c:\\myfile.zip"; 
    var tempFolderPath = "c:\\unzipped"; 

    using (Package pkg = ZipPackage.Open(zipFilePath, FileMode.Open, FileAccess.Read)) 
    { 
     foreach (PackagePart part in pkg.GetParts()) 
     { 
      var target = Path.GetFullPath(Path.Combine(tempFolderPath, part.Uri.OriginalString.TrimStart('/'))); 
      var targetDir = target.Remove(target.LastIndexOf('\\')); 

      if (!Directory.Exists(targetDir)) 
       Directory.CreateDirectory(targetDir); 

      using (Stream source = part.GetStream(FileMode.Open, FileAccess.Read)) 
      { 
       CopyStream(source, File.OpenWrite(target)); 
      } 
     } 
    } 
} 

private static void CopyStream(Stream input, Stream output) 
{ 
    byte[] buffer = new byte[4096]; 
    int read; 
    while ((read = input.Read(buffer, 0, buffer.Length)) > 0) 
    { 
     output.Write(buffer, 0, read); 
    } 
} 

Dinge zu beachten:

  • Das ZIP-Archiv eine [content_types] .xml-Datei in seiner Wurzel haben muss. Dies war für meine Anforderungen kein Problem, da ich das Zippen von ZIP-Dateien kontrollieren werde, die durch diesen Code extrahiert werden. Weitere Informationen zu der [Content_Types] .xml-Datei finden Sie unter: http://msdn.microsoft.com/en-us/magazine/cc163372.aspx Es gibt eine Beispieldatei unter Abbildung 13 des Artikels.

  • Ich habe die CopyStream-Methode nicht getestet, um sicherzustellen, dass sie sich korrekt verhält, wie ich dies ursprünglich für .NET 4.0 mithilfe der Stream.CopyTo() -Methode entwickelt habe.

1
#region CreateZipFile 
    public void StartZip(string directory, string zipfile_path) 
    { 
     Label1.Text = "Please wait, taking backup"; 
      #region Taking files from root Folder 
       string[] filenames = Directory.GetFiles(directory); 

       // path which the zip file built in 
       ZipOutputStream p = new ZipOutputStream(File.Create(zipfile_path)); 
       foreach (string filename in filenames) 
       { 
        FileStream fs = File.OpenRead(filename); 
        byte[] buffer = new byte[fs.Length]; 
        fs.Read(buffer, 0, buffer.Length); 
        ZipEntry entry = new ZipEntry(filename); 
        p.PutNextEntry(entry); 
        p.Write(buffer, 0 , buffer.Length); 
        fs.Close(); 
       } 
      #endregion 

      string dirName= string.Empty; 
      #region Taking folders from root folder 
       DirectoryInfo[] DI = new DirectoryInfo(directory).GetDirectories("*.*", SearchOption.AllDirectories); 
       foreach (DirectoryInfo D1 in DI) 
       { 

        // the directory you need to zip 
        filenames = Directory.GetFiles(D1.FullName); 
        if (D1.ToString() == "backup") 
        { 
         filenames = null; 
         continue; 
        } 
        if (dirName == string.Empty) 
        { 
         if (D1.ToString() == "updates" || (D1.Parent).ToString() == "updates" || (D1.Parent).Parent.ToString() == "updates" || ((D1.Parent).Parent).Parent.ToString() == "updates" || (((D1.Parent).Parent).Parent).ToString() == "updates" || ((((D1.Parent).Parent).Parent)).ToString() == "updates") 
         { 
          dirName = D1.ToString(); 
          filenames = null; 
          continue; 
         } 
        } 
        else 
        { 
         if (D1.ToString() == dirName) ; 
        } 
        foreach (string filename in filenames) 
        { 
         FileStream fs = File.OpenRead(filename); 
         byte[] buffer = new byte[fs.Length]; 
         fs.Read(buffer, 0, buffer.Length); 
         ZipEntry entry = new ZipEntry(filename); 
         p.PutNextEntry(entry); 
         p.Write(buffer, 0, buffer.Length); 
         fs.Close(); 
        } 
        filenames = null; 
       } 
       p.SetLevel(5); 
       p.Finish(); 
       p.Close(); 
      #endregion 
    } 
    #endregion 

    #region EXTRACT THE ZIP FILE 
    public bool UnZipFile(string InputPathOfZipFile, string FileName) 
    { 
     bool ret = true; 
     Label1.Text = "Please wait, extracting downloaded file"; 
     string zipDirectory = string.Empty; 
     try 
     { 
      #region If Folder already exist Delete it 
      if (Directory.Exists(Server.MapPath("~/updates/" + FileName))) // server data field 
      { 
       String[] files = Directory.GetFiles(Server.MapPath("~/updates/" + FileName));//server data field 
       foreach (var file in files) 
        File.Delete(file); 
       Directory.Delete(Server.MapPath("~/updates/" + FileName), true);//server data field 
      } 
      #endregion 


      if (File.Exists(InputPathOfZipFile)) 
      { 
       string baseDirectory = Path.GetDirectoryName(InputPathOfZipFile); 

       using (ZipInputStream ZipStream = new 

       ZipInputStream(File.OpenRead(InputPathOfZipFile))) 
       { 
        ZipEntry theEntry; 
        while ((theEntry = ZipStream.GetNextEntry()) != null) 
        { 
         if (theEntry.IsFile) 
         { 
          if (theEntry.Name != "") 
          { 
           string directoryName = theEntry.Name.Substring(theEntry.Name.IndexOf(FileName)); // server data field 

           string[] DirectorySplit = directoryName.Split('\\'); 
           for (int i = 0; i < DirectorySplit.Length - 1; i++) 
           { 
            if (zipDirectory != null || zipDirectory != "") 
             zipDirectory = zipDirectory + @"\" + DirectorySplit[i]; 
            else 
             zipDirectory = zipDirectory + DirectorySplit[i]; 
           } 
           string first = Server.MapPath("~/updates") + @"\" + zipDirectory; 
           if (!Directory.Exists(first)) 
            Directory.CreateDirectory(first); 


           string strNewFile = @"" + baseDirectory + @"\" + directoryName; 


           if (File.Exists(strNewFile)) 
           { 
            continue; 
           } 
           zipDirectory = string.Empty; 

           using (FileStream streamWriter = File.Create(strNewFile)) 
           { 
            int size = 2048; 
            byte[] data = new byte[2048]; 
            while (true) 
            { 
             size = ZipStream.Read(data, 0, data.Length); 
             if (size > 0) 
              streamWriter.Write(data, 0, size); 
             else 
              break; 
            } 
            streamWriter.Close(); 
           } 
          } 
         } 
         else if (theEntry.IsDirectory) 
         { 
          string strNewDirectory = @"" + baseDirectory + @"\" + 

          theEntry.Name; 
          if (!Directory.Exists(strNewDirectory)) 
          { 
           Directory.CreateDirectory(strNewDirectory); 
          } 
         } 
        } 
        ZipStream.Close(); 
       } 
      } 
     } 
     catch (Exception ex) 
     { 
      ret = false; 
     } 
     return ret; 
    } 
    #endregion 
0

SevenZipSharp ist ein Wrapper um tha 7z.dll und LZMA SDK, das Open Source und kostenlos.

SevenZipCompressor compressor = new SevenZipCompressor(); 
compressor.CompressionLevel = CompressionLevel.Ultra; 
compressor.CompressionMethod = CompressionMethod.Lzma; 
compressor.CompressionMode = CompressionMode.Create; 
compressor.CompressFiles(...); 
Verwandte Themen