Ich möchte in der Lage sein, eine gzip (.gz) -Datei unter Verwendung von gleichzeitigen CPU-Threads zu erzeugen. Das heißt, ich würde separate Blöcke aus der Eingabedatei mit separat initialisierten z_stream
-Datensätzen entleeren.Erstellen eines gzip-Streams aus separat komprimierten Blöcken
Die resultierende Datei sollte von der zlib-Funktion inflate() in einer klassischen single-threaded-Operation gelesen werden können.
Ist das möglich? Auch wenn es angepassten Zlib-Code erfordert? Die einzige Voraussetzung wäre, dass der aktuell vorhandene zlib-Inflationscode damit umgehen könnte.
aktualisieren
Der pigz Quellcode zeigt, wie es funktioniert. Es nutzt einige ausgefeilte Optimierungen, um das Wörterbuch zwischen Chunks zu teilen und die Komprimierungsrate optimal zu halten. Es behandelt weiter das Bit-Packing, wenn eine neuere zlib-Version verwendet wird.
Wie auch immer, ich mag es zu verstehen, wie man meine eigenen, die Dinge einfach zu halten, ohne die Optimierungen pigz
verwendet.
Und während viele Quellcode als die ultimative Dokumentation betrachten (Ed Post, anyone?) habe ich es eher in einfachen Worten erklärt, um Missverständnisse zu vermeiden. (. Während die Dokumente tatsächlich beschreiben, was ziemlich gut der Fall ist, sie nicht allzu gut erklären, was rollen getan werden muss, um eine eigene ist)
den Code aus Surfen, dachte ich, so weit dies viel aus:
Es scheint, dass man einfach jeden komprimierten Chunk unter Verwendung von deflate(..., Z_SYNC_FLUSH)
anstelle von Z_FINISH
erstellt. Allerdings gibt deflateEnd()
einen Fehler dann nicht sicher, ob das ignoriert werden kann. Und man muss die letzte Checksumme manuell über alle Chunks berechnen, obwohl ich mich wundere, wie man die Checksumme am Ende hinzufügt. Es gibt auch eine ziemlich komplexe put_trailer()
-Funktion zum Schreiben eines gzip-Headers - ich frage mich, ob das auch mit zlibs eigenem Code für einfache Fälle gehandhabt werden könnte?
Jede diesbezügliche Klarstellung wird begrüßt.
Auch, Ich realisiere, dass ich enthalten hätte fragen über das Schreiben eines zlib-Stream auf die gleiche Weise, um Multithread-komprimierte Dateien in ein Zip-Archiv zu schreiben. Dort, vermute ich, sind weitere Vereinfachungen möglich, da der komplexere gzip-Header fehlt.
Ich versuche Deflate zu verwenden, indem ich meinen eigenen GZ Header und Trailer hinzufüge. Mit Setzen von Bit 4 in wbits beginnt die gz-Datei mit dem 10-Byte-Header '1F 8B 08 00 00 00 00 00 00 03', dann die deflationierten Daten '95 58 7B 6F D3 48 ...', endend mit CRC und Quelle Länge. So weit, ist es gut. Wenn das Bit 4 gelöscht ist, beginnt es mit "78 DA", dann mit den gleichen Daten "95 58 7B 6F D3 48 ..." und endet mit einer Prüfsumme (Adler?). Was machen die ersten 2 Bytes?Wenn ich nur den Header voranstelle und den CRC und den Ursprung hinzufüge, dekomprimiert er sich nicht als .gz-Datei. Wie generiere ich den reinen gz-Stream ohne Header und Trailer? –
Ich denke, du meinst "Wie erzeuge ich einen defekten Deflate Stream?" Wenn es keinen Header und keinen Trailer gibt, dann ist es definitionsgemäß kein gzip- oder "gz" -Stream. Die Dokumentation in zlib.h sagt, wie man einen defekten Deflate-Stream erstellt. Sie geben 'deflateInit2()' einen negativen 'wbits' Wert. –
Die ersten zwei Bytes des zlib-Streams identifizieren ihn als zlib-Stream und stellen die Komprimierungsmethode und die Fenstergröße bereit. Am Ende wird der Adler-32-Wert in Big-Endian-Reihenfolge gespeichert. (Im Gegensatz zum Gzip-Wrapper, wo die Trailer-Werte in Little-Endian-Reihenfolge gespeichert werden.) –