2009-07-25 4 views
35

Ich möchte die Funktionalität von gzcat | emulieren Schwanz -n.Wie kann ich eine komprimierte Datei erstellen, ohne den gesamten Inhalt zu lesen?

Dies wäre hilfreich für Zeiten, wenn es riesige Dateien (von einigen GB oder so) gibt. Kann ich die letzten Zeilen einer solchen Datei ablesen, ohne sie von Anfang an zu lesen? Ich bezweifle, dass dies nicht möglich ist, da ich für gzip raten würde, würde die Codierung von allen vorherigen Text abhängen.

Aber ich würde immer noch gerne hören, wenn jemand versucht hat, etwas Ähnliches zu tun - vielleicht Untersuchung über einen Kompressionsalgorithmus, der eine solche Funktion bieten könnte.

+0

gzip ist nicht textuell, sondern binär. Es gibt also keine "Zeilen" wie in Textdaten, die "Schwanz" zurückgeben könnte. – Gumbo

+0

Vielleicht möchten Sie [eine ähnliche Frage zu SO] (http://stackoverflow.com/questions/14225751/random-access-to-gzipped-files), [die zlib FAQ] (http://zlib.net) /zlib_faq.html#faq28) und [examples/zran.c] (https://github.com/madler/zlib/blob/master/examples/zran.c) in der [zlib] (http: // zlib. Netz) Verteilung. –

Antwort

36

Nein, das geht nicht. Die zipping algorithm arbeitet an Streams und passt ihre internen Kodierungen an das an, was der Stream enthält, um sein hohes Komprimierungsverhältnis zu erreichen.

Ohne zu wissen, was der Inhalt des Streams vor einem bestimmten Punkt ist, ist es unmöglich zu wissen, wie man von diesem Punkt an die Dekomprimierung vornehmen kann.

Jeder Algorithmus, mit dem Sie beliebige Teile davon dekomprimieren können, erfordert mehrere Durchläufe über die Daten, um sie zu komprimieren.

+6

Dies trifft nur teilweise zu, abhängig davon, wie die Datei erstellt wurde. gzip-Dateien können mehrere Streams enthalten, wobei letzteres völlig unabhängig von früheren Streams ist. Sie können einfach gzip-Dateien miteinander verketten und haben immer noch eine gültige gzip-Datei. Ich kenne die Details nicht, aber ich nehme an, dass es möglich ist, den Ort des letzten solchen Zurücksetzens des Streams zu finden, vorausgesetzt, dass alles, was den Stream geschrieben hat, sehr oft neu startet. – mc0e

3

Wenn Sie die Kontrolle darüber haben, was in die Datei hineingeht, könnten Sie, wenn es sich um eine ZIP-Datei handelt, Stücke mit vorbestimmter Größe mit Dateinamen in aufsteigender numerischer Reihenfolge speichern und dann den letzten Chunk/Datei dekomprimieren.

+3

Das klingt nach einem guten Kompromiss. Dem OP sollte jedoch bewusst sein, dass dadurch das Komprimierungsverhältnis verringert wird. Wenn Tests zeigen, dass die Verhältnisänderung akzeptabel ist, ist dies eine großartige Idee. –

+1

Sie können dies erreichen, indem Sie das Komprimierungswörterverzeichnis teilweise durch eine Datei zurücksetzen. Dadurch müssen Sie die Datei nicht mehr in Blöcke aufteilen. –

7

BGZF wird verwendet, um Index gzip komprimierte BAM-Dateien zu erstellen, die von Samtools erstellt wurden. Diese sind nach dem Zufallsprinzip zugänglich.

http://samtools.sourceforge.net/

+1

Genau. Es ist jedoch nicht nur für Werkzeuge oder für BAMs! Ich glaube, dass es für alle zeilenbegrenzten Daten funktioniert. –

+1

BGZF-Dateien erlauben den Zugriff auf zufällige Byte-Offsets in speziell konstruierten Gzips, indem sie zuerst die Blockgröße begrenzen und dann für jeden Block seine Länge in einem BC-Header speichern (was gzip ignoriert), um einen wahlfreien Zugriff ohne Dekomprimierung zu ermöglichen. Werkzeuge wie BAM speichern Offsets, indem sie den Offset des Blockanfangs und den Offset innerhalb des Blocks speichern. Um eine zeilenorientierte Indexierung zu erhalten, benötigen Sie eine begleitende bai- oder tabix-Datei (obwohl diese Format- und Genom-spezifisch sind), um von Ihrer (n) gewünschten Zeile (n) zum Offset zu mappen. –

1

Wenn es eine Option ist, dann könnte bzip2 ein besserer Komprimierungsalgorithmus für diesen Zweck zu verwenden sein.

Bzip2 verwendet ein Blockkomprimierungsschema. Wenn Sie also ein Stück vom Ende Ihrer Datei nehmen, von dem Sie sicher sind, dass es so groß ist, dass es den gesamten letzten Teil enthält, können Sie es mit bzip2recover wiederherstellen.

Die Blockgröße kann zum Zeitpunkt des Schreibens der Datei ausgewählt werden. Genau das passiert, wenn Sie -1 (oder --fast) als Kompressionsoptionen auf -9 (oder --best) setzen, was Blockgrößen von 100k bis 900k entspricht. Der Standardwert ist 900k.

Die bzip2 Kommandozeilen-Tools geben Ihnen keine nette, freundliche Möglichkeit, dies mit einer Pipeline zu tun, aber dann ist bzip2 nicht stream-orientiert, vielleicht ist das nicht überraschend.

Verwandte Themen