2016-08-19 3 views
1

Ich versuche, eine mehrteilige Zip-Datei mit Dateien einer Gesamtgröße von 17 GB, mit IonicZip zu erstellen.Erstellen von großen mehrteiligen Zip mit Ionic schlägt mit OutOfMemoryException

Jeder Zip-Teil ist nicht größer als etwa 500 MB.

zip.MaxOutputSegmentSize = 500000000; 

Die Dateien, die in die Zip gehen, sind in verschiedenen Größen je, aber nie größer als 350 MB, in der Regel viel kleiner, nur ein paar KB oder MB.

Meine Maschine, wo ich die Zip-Datei erstellen, hat 4 GB RAM.

Wenn ich die Zip-Erstellung in meinem Programm starte, bekomme ich irgendwann einen OutOfMemoryException wegen des verwendeten RAM.

(Das gleiche funktioniert, wenn die Gesamtgröße aller Dateien etwa 2 GB statt 17 GB beträgt).

Der Code:

ZipFile zip = new ZipFile(zipFileName, Encoding.UTF8); 
zip.CompressionLevel = CompressionLevel.BestCompression; 

zip.ParallelDeflateThreshold = -1; // https://stackoverflow.com/questions/11981143/compression-fails-when-using-ionic-zip 
zip.MaxOutputSegmentSize = 500000000; // around 500MB 

[...] 

while (...) 
{ 
    zip.AddEntry(adjustedFilePath, File.ReadAllBytes(filepath)); 
} 

zip.Save(); 

Ich frage mich, wie IonicZip Griffe zip.save in Kombination mit mehrteiligen Schöpfung. Es sollte nicht notwendig sein, alle Multi-Teile im Speicher zu halten, sondern nur die aktuelle, nicht?

Und da ich zip.MaxOutputSegmentSize auf nur etwa 500MB eingestellt habe und die maximale Größe einer einzelnen Datei, die in die ZIP geht, nie mehr als 350MB ist, sehe ich nicht, warum sie so viel Speicher verbrauchen sollte.

Auf der anderen Seite, wenn die OutOfMemoryException auftritt, ist noch nicht einmal ein einzelner Teil des Multi-Part auf die Festplatte geschrieben. Normalerweise, mit einer kleineren Anzahl von Dateien, bei denen die Zip-Erstellung erfolgreich ist, befinden sich die verschiedenen Teile auf dem Dateisystem mit unterschiedlichen Erstellungs-Zeitstempeln. Jeweils 5 Sekunden. Ich bin also wirklich nicht sicher, was IonicZip intern genau macht, bis es den ersten Zip-Teil ausspuckt.

Entschuldigung, ich bin neu in C# und .NET. Ist der IonicZip die beste Bibliothek dafür? Könnte ich stattdessen das System.IO.Compression- oder System.IO.Packaging-Paket verwenden (ich habe nicht gesehen, dass sie mehrteilige Reißverschlüsse unterstützen) oder das kommerzielle Xceed?

Beiträge, die ich bereits überprüft, aber nicht helfen:

Antwort

0

Die Lösung, die ich gefunden habe, scheint in Bezug auf den Aufwand am besten zu sein (ich will das Rad nicht neu erfinden und mehrteilige Logik für das Standard-Zip/Komprimierungspaket schreiben, scheint so ein Standard) Sache, die Teil eines Zipping-Pakets sein sollte) ist Xceed zu verwenden und ziemlich die gleiche Code-Logik wie ich für IonicZip verwenden.

Es scheint, dass IonicZip es nicht wirklich effizient in Bezug auf Speicher verarbeitet. Xceed funktioniert ohne größere Speicherauslastung.

 using Xceed.Zip; 
     using Xceed.FileSystem; 

     [...] 

     ZipArchive zip = new ZipArchive(new DiskFile(zipFileName)); 
     zip.SplitNameFormat = SplitNameFormat.PkZip; 
     zip.SplitSize = 500000; 
     zip.DefaultCompressionLevel = Xceed.Compression.CompressionLevel.Highest; 
     zip.TempFolder = new DiskFolder(@"C:\temp"); 
     new DiskFolder(localSourceFolder).CopyFilesTo(zip, true, true); 
0

Ich schlage vor, mit dem in .net-System gebaut. IO.Compression-Namespace-Klassen zum Zippen/Entpacken von Dateien; Sie sind streambasiert, während Ihr Beispiel hier keine Streams verwendet. Sie müssen also RAM verwenden, um die komprimierten Daten zu speichern. Mit den systemeigenen .net-Bibliotheken können Sie komprimierte Daten in Blöcken in den Ausgabestrom schreiben.

+0

Danke. Unterstützt dieses Paket mehrteilige Reißverschlüsse, weil ich in Google oder https://msdn.microsoft.com/de-de/library/system.io.compression.zipfile(v=vs.110) nichts darüber finden konnte? .aspx –

+0

Zip funktioniert, aber die anderen (GZip) nicht. – PhillipH

+0

Können Sie mich auf einige Online-API-Dokumente verweisen, in denen die Split-Größe festgelegt werden kann? Ich kann immer noch nicht sehen, wo ich das über das 'System.IO.Compression'-Paket machen kann. Im Moment teste ich die Xceed (https://xceed.com/xceed-zip-for-net/) Bibliothek als Alternative, wobei ich einfach sagen kann: zip.splitSize = 500000000. Bis jetzt kann ich keine Erhöhung der Speicherauslastung sehen, aber es ist immer noch meine 17GB zippen. –

Verwandte Themen