2015-12-10 7 views
6

Erstellen von bzip2 archivierten Daten in PHP ist sehr einfach dank seiner Implementierung in bzcompress. In meiner gegenwärtigen Anwendung kann ich nicht einfach die Eingabedatei in einen String lesen und dann bzcompress oder bzwrite aufrufen. Die PHP-Dokumentation macht nicht klar, ob aufeinanderfolgende Aufrufe an bzwrite mit relativ kleinen Datenmengen das gleiche Ergebnis liefern, als wenn die gesamte Datei auf einen Schlag komprimiert würde. Ich meine etwas entlang der Linien vonPiecemeal bzcompression für große Dateien in PHP

$data = file_get_contents('/path/to/bigfile'); 
$cdata = bzcompress($data); 

Ich versuchte unter

function makeBZFile($infile,$outfile) 
{ 
$fp = fopen($infile,'r'); 
$bz = bzopen($outfile,'w'); 
while (!feof($fp))  
{ 
    $bytes = fread($fp,10240); 
    bzwrite($bz,$bytes); 
} 
bzclose($bz); 
fclose($fp); 
} 

function unmakeBZFile($infile,$outfile) 
{ 
$bz = bzopen($infile,'r'); 
while (!feof($bz)) 
{ 
    $str = bzread($bz,10240); 
    file_put_contents($outfile,$str,FILE_APPEND); 
} 
} 

set_time_limit(1200); 
makeBZFile('/tmp/test.rnd','/tmp/test.bz'); 
unmakeBZFile('/tmp/test.bz','/tmp/btest.rnd'); 

diesen Code zu testen ich zwei Dinge

    hat gezeigt, ein Stück für Stück bzcompression mit den Routinen aus
  • I verwendet makeBZFile und unmakeBZFile, um eine SQLite-Datenbank zu komprimieren und dann zu dekomprimieren - was ich schließlich tun muss.
  • Ich habe eine 50Mb mit Zufallsdaten gefüllt dd if=/dev/urandom of='/tmp.test.rnd bs=50M count=1

In beiden Fällen I a diff original.file decompressed.file durchgeführt und festgestellt, dass die beiden identisch waren.

Alles sehr nett, aber es ist mir nicht klar, warum das funktioniert. Die PHP-Dokumentation besagt, dass bzread(bzpointer,length) ein Maximum length Bytes von UNCOMPRESSED Daten liest. Wenn mein Code unten Woring ist, ist, weil ich die bzwite und bzread Größe auf 10240 Bytes erzwinge.

Was kann ich nicht sehen, ist nur, wie bzread weiß, wie lenth Bytes UNCOMPRESSED Daten zu holen. Ich habe die format of a bzip2 file ausgecheckt. Ich kann nicht sehen, dass es dort etwas gibt, das hilft, die unkomprimierte Datenlänge für einen Block der .bz-Datei leicht herzustellen.

Ich vermute, es gibt eine Lücke in meinem Verständnis davon, wie das funktioniert - oder die Tatsache, dass mein Code unten scheint, um eine korrekte stückweise Komprimierung durchzuführen, ist rein zufällig.

Ich würde gerne ein paar Erklärungen hier zu schätzen wissen.

Antwort

3

Um zu verstehen, wie die Dekomprimierung die Länge von Bytes bekommen, muss man zuerst die Komprimierung verstehen. Es scheint, dass Sie nichts über Kompression algorigthim wissen.

BZIP2

Entscheidend Algorithmus von BZIP2 ist die Burrows Wheeler transformation (BWT), die für folgende Codieren der ursprünglichen Daten in eine geeignete Form umwandelt. Die aktuelle Version wendet eine Huffman code an. Der Kompressionsalgorithmus verarbeitet die Daten in Blöcken, die völlig unabhängig von jedem Block sind. Blockgrößen können in einem Bereich von 1-9 (100.000 - 900.000 Bytes) eingestellt werden.

BZIP2 Datenstruktur

Die ersten beiden Zeichen von komprimiertem String mit dem Buchstaben ‚BZ‘ und danach 1 Byte für algorigthim verwendet starten. Danach folgt sofort die Identifikation der Blockgröße, die für die gesamte Datei gilt (h1, h2, h3 bis h9).Der Parameter gibt die Blockgröße in Einheiten von 1-9 (100.000 - 900.000 Byte) an.

Aktuelle Originaldaten werden in Blöcken entsprechend der gewählten Größe gespeichert und werden einzeln mit einer CRC32-Prüfsumme geschützt. Zusätzlich führt eine 48-Bit-Kennung jeden Block ein. Diese Blockstruktur ermöglicht eine teilweise Rekonstruktion beschädigter Dateien.

GZIP/BZIP

gzip und bzip2 sind funktionell gleichwertig. Ein Vorteil von GZIP ist, dass es einen Stream komprimieren kann, eine Sequenz, in die man nicht zurückblicken kann. Dies macht es zum offiziellen Komprimierer von http-Streams. GZZIP DEFLATE RFC 1951 komprimierte Datenformat-Spezifikation und GUNZIP RFC 1952 Dateiformat Spezifikation sind veröffentlichte Dokumente.

GIP erklärt

GZIP Explained

+0

danke für die Antwort. Sie haben vielleicht bemerkt, dass ich in meiner Frage einen Link zum BZIP-Dateiformat angegeben habe, das ich vor dem Stellen der Frage studiert hatte. Ihre Antwort hilft zu verstehen, wie der 'bzwrite' Daten stückweise schreibt. Es ist mir weniger klar, wie es 'bzread' gelingt, die angegebene Anzahl * unkomprimierter * Bytes zu lesen. Vorausgesetzt, dass der Grad der Komprimierung abhängig von den Daten in jedem Block variieren wird, ist es nicht so einfach zu denken "* er will X Bytes von unkomprimierten Daten, so lass mich nur die nächsten X/unkomprimierten_size Blöcke holen" – DroidOS

+0

Es ist nicht die glatte Jacke Formel zum Lesen von Bytes in Unkomprimierungsbytes. Zuerst wird der Huffman-Baum im Speicher decodiert und entsprechend dem Baum werden die komprimierten Daten unkomprimiert. – Vineet1982

+0

Alles, was du noch wissen musst, lass es mich wissen oder akzeptiere die Antwort – Vineet1982