wake-up-neo.net

Entpacken Sie Dateien programmatisch in .net

Ich versuche, eine gezippte Datei programmatisch zu entpacken.

Ich habe versucht, die System.IO.Compression.GZipStream-Klasse in .NET zu verwenden, aber wenn meine App ausgeführt wird (tatsächlich ein Komponententest), erhalte ich diese Ausnahme: 

System.IO.InvalidDataException: Die magische Zahl im GZip-Header ist nicht korrekt. Stellen Sie sicher, dass Sie einen GZip-Stream übergeben.

Jetzt stelle ich fest, dass eine .Zip-Datei nicht mit einer .gz-Datei identisch ist und dass GZip nicht mit Zip identisch ist. 

Da ich jedoch in der Lage bin, die Datei zu extrahieren, indem Sie manuell auf die gezippte Datei doppelklicken und dann auf die Schaltfläche "Alle Dateien extrahieren" klicken, denke ich, dass dies auch im Code möglich sein sollte. 

Deshalb habe ich versucht, Process.Start() mit dem Pfad zur gezippten Datei als Eingabe zu verwenden. Dadurch öffnet meine App ein Fenster, in dem der Inhalt der gezippten Datei angezeigt wird. Das ist in Ordnung, aber die App wird auf einem Server ohne Server installiert, um auf die Schaltfläche "Alle Dateien extrahieren" zu klicken. 

Wie bekomme ich also meine App, um die Dateien in den gezippten Dateien zu extrahieren?

Oder gibt es eine andere Möglichkeit, dies zu tun? Ich bevorzuge es lieber im Code, ohne Bibliotheken oder Apps von Drittanbietern herunterzuladen. die Sicherheitsabteilung ist darüber nicht so schlau ...

189
Petteri

Wir haben SharpZipLib bei vielen Projekten erfolgreich eingesetzt. Ich weiß, dass es sich um ein Tool von Drittanbietern handelt, aber der Quellcode ist enthalten und könnte Einblick geben, wenn Sie das Rad hier neu erfinden.

51
Chris Conway

Mit .NET 4.5 können Sie jetzt Dateien mit dem .NET-Framework entpacken:

using System;
using System.IO;

namespace ConsoleApplication
{
  class Program
  {
    static void Main(string[] args)
    {
      string startPath = @"c:\example\start";
      string zipPath = @"c:\example\result.Zip";
      string extractPath = @"c:\example\extract";

      System.IO.Compression.ZipFile.CreateFromDirectory(startPath, zipPath);
      System.IO.Compression.ZipFile.ExtractToDirectory(zipPath, extractPath);
    }
  }
}

Der obige Code wurde direkt aus der Microsoft-Dokumentation übernommen: http://msdn.Microsoft.com/en-us/library/ms404280(v=vs.110).aspx

ZipFile ist in der Assembly System.IO.Compression.FileSystem enthalten. (Danke Nateirvin ... siehe Kommentar unten)

432
bsara

Für .Net 4.5+

Es ist nicht immer erwünscht, die unkomprimierte Datei auf die Festplatte zu schreiben. Als ASP.Net-Entwickler müsste ich mich mit den Berechtigungen beschäftigen, Rechte für meine Anwendung zum Schreiben in das Dateisystem zu erteilen. Durch die Arbeit mit Streams im Speicher kann ich all das umgehen und die Dateien direkt lesen:

using (ZipArchive archive = new ZipArchive(postedZipStream))
{
    foreach (ZipArchiveEntry entry in archive.Entries)
    {
         var stream = entry.Open();
         //Do awesome stream stuff!!
    }
}

Alternativ können Sie die dekomprimierte Datei trotzdem auf die Festplatte schreiben, indem Sie ExtractToFile() aufrufen:

using (ZipArchive archive = ZipFile.OpenRead(pathToZip))
{
    foreach (ZipArchiveEntry entry in archive.Entries)
    {
        entry.ExtractToFile(Path.Combine(destination, entry.FullName));
    }
} 

Um die ZipArchive-Klasse verwenden zu können, müssen Sie einen Verweis auf den System.IO.Compression-Namespace hinzufügen.

69
Mister Epic

Kostenlose und keine externen DLL -Dateien. Alles ist in einer CS-Datei. Ein Download ist nur die CS-Datei, ein anderer Download ist ein sehr leicht verständliches Beispiel. Ich habe es gerade heute ausprobiert und ich kann nicht glauben, wie einfach das Setup war. Beim ersten Versuch hat es funktioniert, keine Fehler, nichts.

https://github.com/jaime-olivares/zipstorer

49
Lukas

Verwenden Sie die DotNetZip-Bibliothek unter http://www.codeplex.com/DotNetZip

klassenbibliothek und Toolset zum Bearbeiten von Zip-Dateien. Verwenden Sie VB, C # oder eine beliebige .NET-Sprache, um Zip-Dateien einfach zu erstellen, zu extrahieren oder zu aktualisieren ...

DotNetZip funktioniert auf PCs mit dem vollständigen .NET Framework und auch auf mobilen Geräten, die das .NET Compact Framework verwenden. Erstellen und lesen Sie Zip-Dateien in VB, C # oder einer beliebigen .NET-Sprache oder einer anderen Skriptumgebung ...

Wenn Sie nur eine bessere DeflateStream- oder GZipStream-Klasse benötigen, um die in .NET BCL integrierte zu ersetzen, hat dies auch DotNetZip. DeflateStream und GZipStream von DotNetZip sind in einer eigenständigen Assembly verfügbar, die auf einem .NET-Port von Zlib basiert. Diese Streams unterstützen die Komprimierungsstufen und bieten eine wesentlich bessere Leistung als die integrierten Klassen. Es gibt auch einen ZlibStream, um das Set abzuschließen (RFC 1950, 1951, 1952) ...

27
Sam Axe
String ZipPath = @"c:\my\data.Zip";
String extractPath = @"d:\\myunzips";
ZipFile.ExtractToDirectory(ZipPath, extractPath);

Um die ZipFile-Klasse zu verwenden, müssen Sie einen Verweis auf die System.IO.Compression.FileSystem-Assembly in Ihrem Projekt hinzufügen

8
Mahadev Mane

Standard-Zip-Dateien verwenden normalerweise den Deflate-Algorithmus.

Um Dateien ohne Bibliotheken von Drittanbietern zu extrahieren, verwenden Sie DeflateStream. Sie benötigen etwas mehr Informationen zum ZIP-Archivformat, da Microsoft nur den Kompressionsalgorithmus bereitstellt.

Sie können auch versuchen, zipfldr.dll zu verwenden. Es ist die Komprimierungsbibliothek von Microsoft (komprimierte Ordner aus dem Menü Senden an). Es scheint eine Com-Bibliothek zu sein, aber es ist nicht dokumentiert. Möglicherweise können Sie es durch Experimentieren für Sie zum Laufen bringen.

2
Kenneth Cochran

Dies wird es tun System.IO.Compression.ZipFile.ExtractToDirectory(ZipName, ExtractToPath)

1
Ilya Kochetov

Ich verwende dies, um mehrere Dateien zu komprimieren oder zu entpacken. Das Regex-Material ist nicht erforderlich, aber ich verwende es, um den Datumsstempel zu ändern und unerwünschte Unterstriche zu entfernen. Ich benutze die leere Zeichenfolge in der Compress >> zipPath-Zeichenfolge, um allen Dateien bei Bedarf ein Präfix hinzuzufügen. Außerdem kommentiere ich Compress () oder Decompress () normalerweise basierend auf dem, was ich mache.

using System;
using System.IO.Compression;
using System.IO;
using System.Text.RegularExpressions;

namespace ZipAndUnzip
{
    class Program
    {
        static void Main(string[] args)
        {
            var directoryPath = new DirectoryInfo(@"C:\your_path\");

            Compress(directoryPath);
            Decompress(directoryPath);
        }

        public static void Compress(DirectoryInfo directoryPath)
        {
            foreach (DirectoryInfo directory in directoryPath.GetDirectories())
            {
                var path = directoryPath.FullName;
                var newArchiveName = Regex.Replace(directory.Name, "[0-9]{8}", "20130913");
                newArchiveName = Regex.Replace(newArchiveName, "[_]+", "_");
                string startPath = path + directory.Name;
                string zipPath = path + "" + newArchiveName + ".Zip";

                ZipFile.CreateFromDirectory(startPath, zipPath);
            }

        }

        public static void Decompress(DirectoryInfo directoryPath)
        {
            foreach (FileInfo file in directoryPath.GetFiles())
            {
                var path = directoryPath.FullName;
                string zipPath = path + file.Name;
                string extractPath = Regex.Replace(path + file.Name, ".Zip", "");

                ZipFile.ExtractToDirectory(zipPath, extractPath);
            }
        }


    }
}
1
Phyllip Hamby

Sie können dies alles mit .NET 3.5 mit DeflateStream tun. In .NET 3.5 fehlt die Möglichkeit, die Dateikopfabschnitte zu verarbeiten, die zum Organisieren der komprimierten Dateien verwendet werden. PKWare hat diese Informationen veröffentlicht, die Sie zur Verarbeitung der Zip-Datei verwenden können, nachdem Sie die verwendeten Strukturen erstellt haben. Es ist nicht besonders belastend und es ist eine bewährte Methode beim Erstellen von Tools ohne Verwendung von Drittanbietercode.

Es ist keine einzeilige Antwort, aber es ist völlig machbar, wenn Sie willens und in der Lage sind, sich die Zeit selbst zu nehmen. Ich habe in ein paar Stunden einen Kurs geschrieben, der dies in wenigen Stunden erledigt hat. Was ich daraus habe, ist die Möglichkeit, Dateien nur mit .NET 3.5 zu komprimieren und zu entpacken.

1
Michael Blake

Von hier :

Komprimierte GZipStream-Objekte geschrieben zu einer Datei mit der Erweiterung .gz kann dekomprimiert werden mit vielen gemeinsamen Kompressionswerkzeuge; diese Klasse stellt von sich aus nicht Funktionalität zum Hinzufügen von Dateien zu oder Extrahieren von Dateien aus ZIP-Archiven.

1
RedWolves

Bisher habe ich cmd-Prozesse verwendet, um eine .iso-Datei zu extrahieren, in einen temporären Pfad vom Server zu kopieren und auf einem USB-Stick zu extrahieren. Ich habe kürzlich herausgefunden, dass dies perfekt mit .ISO's funktioniert, die weniger als 10 GB sind. Bei einer Iso wie 29 GB bleibt diese Methode irgendwie hängen.

    public void ExtractArchive()
    {
        try
        {

            try
            {
                Directory.Delete(copyISOLocation.OutputPath, true); 
            }
            catch (Exception e) when (e is IOException || e is UnauthorizedAccessException)
            {
            }

            Process cmd = new Process();
            cmd.StartInfo.FileName = "cmd.exe";
            cmd.StartInfo.RedirectStandardInput = true;
            cmd.StartInfo.RedirectStandardOutput = true;
            cmd.StartInfo.CreateNoWindow = true;
            cmd.StartInfo.UseShellExecute = false;
            cmd.StartInfo.WindowStyle = ProcessWindowStyle.Normal;

            //stackoverflow
            cmd.StartInfo.Arguments = "-R";

            cmd.Disposed += (sender, args) => {
                Console.WriteLine("CMD Process disposed");
            };
            cmd.Exited += (sender, args) => {
                Console.WriteLine("CMD Process exited");
            };
            cmd.ErrorDataReceived += (sender, args) => {
                Console.WriteLine("CMD Process error data received");
                Console.WriteLine(args.Data);
            };
            cmd.OutputDataReceived += (sender, args) => {
                Console.WriteLine("CMD Process Output data received");
                Console.WriteLine(args.Data);
            };

            //stackoverflow


            cmd.Start();

            cmd.StandardInput.WriteLine("C:");
            //Console.WriteLine(cmd.StandardOutput.Read());
            cmd.StandardInput.Flush();

            cmd.StandardInput.WriteLine("cd C:\\\"Program Files (x86)\"\\7-Zip\\");
            //Console.WriteLine(cmd.StandardOutput.ReadToEnd());
            cmd.StandardInput.Flush();

            cmd.StandardInput.WriteLine(string.Format("7z.exe x -o{0} {1}", copyISOLocation.OutputPath, copyISOLocation.TempIsoPath));
            //Console.WriteLine(cmd.StandardOutput.ReadToEnd());
            cmd.StandardInput.Flush();
            cmd.StandardInput.Close();
            cmd.WaitForExit();
            Console.WriteLine(cmd.StandardOutput.ReadToEnd());
            Console.WriteLine(cmd.StandardError.ReadToEnd());
0
Răzvan Bălan

sie können Info-unzip Befehlszeile cod verwenden. Sie müssen nur unzip.exe von der offiziellen Website von Info-unzip herunterladen.

 internal static void Unzip(string sorcefile)
    {
        try
        {
            AFolderFiles.AFolderFilesDelete.DeleteFolder(TempBackupFolder); // delete old folder   
            AFolderFiles.AFolderFilesCreate.CreateIfNotExist(TempBackupFolder); // delete old folder   
           //need to Command command also to export attributes to a Excel file
            System.Diagnostics.Process process = new System.Diagnostics.Process();
            System.Diagnostics.ProcessStartInfo startInfo = new System.Diagnostics.ProcessStartInfo();
            startInfo.WindowStyle = System.Diagnostics.ProcessWindowStyle.Hidden; // window type
            startInfo.FileName = UnzipExe;
            startInfo.Arguments = sorcefile + " -d " + TempBackupFolder;
            process.StartInfo = startInfo;
            process.Start();
            //string result = process.StandardOutput.ReadToEnd();
            process.WaitForExit();
            process.Dispose();
            process.Close();
        }
        catch (Exception ex){ throw ex; }
    }        
0
Arun kumar

Ich habe heute über this (Unzip package auf NuGet) erfahren, da ich in DotNetZip einen harten Fehler gefunden habe und festgestellt habe, dass in DotNetZip in den letzten zwei Jahren nicht wirklich viel gearbeitet wurde.

Das Unzip-Paket ist schlank und hat die Arbeit für mich erledigt - es hatte nicht den Fehler, den DotNetZip hatte. Es war auch eine recht kleine Datei, die sich bei der eigentlichen Dekomprimierung auf die Microsoft BCL stützte. Ich konnte leicht Anpassungen vornehmen, die ich brauchte (um den Fortschritt beim Dekomprimieren verfolgen zu können). Ich empfehle es.

0
Per Lundberg

Von Einbettungsressourcen:

using (Stream _pluginZipResourceStream = Assembly.GetExecutingAssembly().GetManifestResourceStream(programName + "." + "filename.Zip"))
{
    using (ZipArchive Zip = new ZipArchive(_pluginZipResourceStream))
    {
        Zip.ExtractToDirectory(Application.StartupPath);
    }
}
0
Steve Rousseau