2013-10-18 1 views
6

Als Teil unseres Installer-Builds müssen wir Tausende von großen Datendateien in etwa zehn oder zwanzig "Pakete" mit einigen Hundert (oder sogar Tausenden) Dateien zippen, die alle davon abhängig sind, dass sie mit den anderen Dateien aufbewahrt werden im Paket. (Sie werden zusammen versioniert, wenn Sie das tun.)Können Sie Datendateien, die zu einem späteren Zeitpunkt in eine Zip-Datei eingefügt werden sollen, vorkomprimieren, um die Leistung zu verbessern?

Dann wählt der Benutzer während der tatsächlichen Installation aus, welche Pakete in ihrem System enthalten sein sollen. Dadurch können sie auch Updates für die Pakete von unserer Site als eine große, versionierte Datei herunterladen, anstatt sie zu bitten, Tausende von Einzeldateien herunterzuladen, die dazu führen könnten, dass sie mit anderen im selben Paket nicht mehr synchron sind.

Da es sich um Datendateien handelt, ändern sich einige von ihnen regelmäßig während der Entwurfs- und Codierungsschritte, was bedeutet, dass wir alle Dateien in diesem bestimmten Zip-Paket erneut komprimieren müssen, auch wenn nur eine Datei geändert wurde. Das bedeutet, dass der Verpackungsschritt unseres Installers jedes Mal mehr als eine Stunde dauern muss, wobei die meisten davon dazu dienen, Dinge, die wir nicht berührt haben, wieder zu komprimieren.

Wir haben uns darum gekümmert, die Zip-Pakete allein zu lassen und dann bestimmte Dateien zu ersetzen, aber das Einfügen und Entfernen großer Dateien aus der Mitte einer Zip-Datei bringt uns nicht so viel Leistung. (Ein wenig, aber nicht genug, dass es es wert ist.)

Ich frage mich, ob es möglich ist, Dateien in einen zwischengespeicherten rohen "komprimierten Zustand" vorzuverarbeiten, der übereinstimmt, wie es in das Zip-Paket geschrieben würde, aber nur die Daten selbst, nicht die Zip-Header-Informationen, etc.

Mein Gedanke ist, wenn das möglich ist, während unseres Build-Schrittes würden wir zuerst nach jeder Datendatei suchen, die keinen komprimierten Cache damit verbunden hat und wenn nicht, würden wir diese Datei komprimieren und das Ergebnis in den Cache schreiben.

Als nächstes würden wir einfach alle Caches in einem Dateistrom zusammenfügen und jeden geeigneten Zip-Header hinzufügen, der für die Dateien benötigt wird.

Dies würde bedeuten, dass wir immer noch die gesamte Zip bei jedem Build neu erstellen, aber wir komprimieren nur Daten, die sich geändert haben. Der Rest würde nur so geschrieben werden, wie es ist, was sehr schnell ist, da es ein direktes Schreiben auf die Platte ist. Und wenn sich eine Datendatei ändert, wird ihr Cache zerstört, also wird der nächste Build-Pass neu erstellt.

Allerdings bin ich nicht sicher, dass so etwas möglich ist. Ist es, und wenn ja, gibt es irgendeine Dokumentation, um zu zeigen, wie man das versucht?

+1

Gibt es einen Grund, warum Sie nicht jede Datei einzeln komprimieren können? Siehst du einen großen Dateigewinn, indem du sie alle in eine riesige Zip-Datei steckst? –

+0

Versuchen Sie, [diese Frage SO] (http://stackoverflow.com/questions/1410533/deflate-compression-stream-where-pre-compressed-da-can-be-inserted-does-a-ne/1435813#) 1435813) – Icemanind

+1

Zip-Dateien sind keine "festen Archive". Es sollte möglich sein. – usr

Antwort

0

Ich kann nicht scheinen, eine tatsächliche exe zu finden, die diese Art von Funktionalität implementiert. Es scheint, dass die meisten vorhandenen Tools, die ich ausprobiert habe, die die Möglichkeit haben, den Datenstrom erneut zu verarbeiten (komprimieren), wie Sie bereits erwähnt haben.

Es scheint jedoch, was Sie beschreiben, kann getan werden, wenn Sie oder jemand es schreiben möchte. Wenn Sie sich diesen Link für die ZIP file format specification ansehen, können Sie sich einen Überblick über die Struktur verschaffen, die Sie analysieren und verarbeiten müssten. Es sieht so aus, als könnten Sie ziemlich schnell von Datei zu Datei gehen und die interessanten Dateien verwerfen und dann in Ihren neuen/aktualisierten Dateien zusammenführen. Sie müssten immer noch ein neues zentrales Verzeichnis (siehe Abschnitt 4.3.6 des oben verlinkten Dokuments) in Ihrem neuen Zielarchiv erstellen.

Nach ein wenig mehr graben, die DotNetZip Library forum has a message Frage nach der gleichen Art von Funktionalität, die auch eine Beschreibung wie ich oben beschrieben. Es verweist auch auf diese document, die darauf hinweist, dass Unterstützung für die DotNetZip-Bibliothek hinzugefügt werden kann, damit Sie weiter experimentieren können.

+0

aber möglich? nur vielleicht –

+0

Ich würde nicht Header "chopping/merging". Ich hätte nichts dagegen, den Header jedes Mal neu zu erstellen, wenn wir ein "Paket" machen. Aus diesem Grund habe ich ausdrücklich erwähnt, dass jede Datei auf einen "rohen" komprimierten "Zwischenzustand" komprimiert wird, dh ohne die Header-Informationen, die wir erstellen würden, wenn wir die Rohdaten zusammenfügen, um die endgültige Datei zu erstellen. Sinn ergeben? – MarqueIV

+0

@MarqueIV Sagen Sie so, als ob Sie es gelöst haben ...Oder ist die Stream-Art der Komprimierung, die Sie auswählen, im Weg? –

1

Sie könnten jede Datei vorher zippen und dann am Ende ohne Komprimierung "zippen", um sie schnell zu einem verteilbaren Paket zusammenzufassen. Es ist nicht so effizient wie die Komprimierung aller Daten auf einmal, aber es sollte schneller sein, um Änderungen vorzunehmen.

+0

Ja, wir haben darüber nachgedacht, aber das erfordert, dass jede Datei einzeln entpackt wird, nachdem die Haupt-Wrapper-Zip-Datei entpackt wurde, wodurch die großen Build-Zeiten von unserem Installations-Build auf die Benutzer-Installation verschoben werden Das Entpacken von 1000 Dateien ist wesentlich langsamer als das Entpacken eines großen Zip-Archivs mit denselben 1000 Dateien. Hier geht es mehr um Geschwindigkeit und das Zusammenhalten von Dateien als um die Größe. – MarqueIV

2

Ja, das ist möglich. Am einfachsten wäre es, jede Datei einzeln mit einem Eintrag in ihr eigenes zugehöriges Zip-Archiv zu zippen. Wenn eine Datei geändert wird, ersetzen Sie die zugehörige ZIP-Datei, um alle Dateien auf dem neuesten Stand zu halten. Dann können Sie ein einfaches Programm schreiben, um eine Reihe dieser Zip-Dateien mit einem einzigen Eintrag zu erstellen und sie in eine einzige Zip-Datei zusammenzuführen. Sie müssen sich auf die Dokumentation in der PKZip appnote beziehen. Sieh dir das an.

Nun, da Sie die Appnote gelesen haben, müssen Sie den lokalen Header, die Daten und den zentralen Header aus jeder einzelnen Zip-Datei verwenden, den lokalen Header und die Daten sequenziell in die neue Zip-Datei schreiben. und speichern Sie den zentralen Header und die Offsets der lokalen Header in der neuen Datei. Speichern Sie am Ende der neuen Datei den aktuellen Offset, schreiben Sie ein neues zentrales Verzeichnis unter Verwendung der von Ihnen gespeicherten zentralen Header, aktualisieren Sie die Offsets entsprechend und enden Sie mit einem neuen Ende des zentralen Verzeichniseintrags mit dem Offset des Anfangs des zentralen Verzeichnisses .

Update:

ich beschlossen, dass dies eine nützliche genug Sache war, zu schreiben. Sie können es erhalten here.

+0

+1. Wikipedia hat auch eine lesbare Beschreibung im zip-Format: http://en.wikipedia.org/wiki/Zip_(file_format) –

+0

Sieht sehr vielversprechend aus! Ich werde sehen, ob ich hier einen Proof-of-Concept machen kann und wenn diese Informationen stimmen, werden Sie die Antwort bekommen. Vielen Dank! – MarqueIV

+0

@MarqueIV: Proof-of-Concept-Code als Antwort verknüpft. –

Verwandte Themen