Es ist wichtig zu verstehen, dass es hier einen Kompromiss gibt.
tar
bedeutet Bandarchivierer . Auf einem Band lesen und schreiben Sie meistens nacheinander. Bänder werden heutzutage selten verwendet, werden aber tar
immer noch verwendet, um ihre Daten als Stream zu lesen und zu schreiben.
Du kannst tun:
tar cf - files | gzip | ssh host 'cd dest && gunzip | tar xf -'
Das kann man nicht mit zip
oder ähnlichem machen.
Sie können den Inhalt eines zip
Archivs nicht einmal auflisten, ohne ihn zuerst lokal in einer durchsuchbaren Datei zu speichern. Denkt wie:
curl -s https://github.com/dwp-forge/columns/archive/v.2016-02-27.zip | unzip -l /dev/stdin
wird nicht funktionieren.
Um dieses schnelle Lesen des Inhalts zip
oder dergleichen zu erreichen, muss ein Index erstellt werden. Dieser Index kann am Anfang der Datei gespeichert werden (in diesem Fall kann er nur in reguläre Dateien geschrieben werden, nicht in Streams) oder am Ende. Dies bedeutet, dass der Archivierer sich alle Archivmitglieder merken muss, bevor er am Ende gedruckt wird und bedeutet, dass ein abgeschnittenes Archiv möglicherweise nicht wiederhergestellt werden kann.
Das bedeutet auch, dass Archivmitglieder einzeln komprimiert werden müssen, was ein viel geringeres Komprimierungsverhältnis bedeutet, insbesondere wenn viele kleine Dateien vorhanden sind.
Ein weiterer Nachteil bei Formaten wie zip
ist, dass die Archivierung mit der Komprimierung verknüpft ist. Sie können den Komprimierungsalgorithmus nicht auswählen. Sehen Sie, wie tar
Archive früher mit compress
( tar.Z
) komprimiert wurden , dann mit gzip
, dann bzip2
, xz
als neue, leistungsfähigere Komprimierungsalgorithmen entwickelt wurden. Gleiches gilt für die Verschlüsselung. Wer würde zip
heutzutage der Verschlüsselung vertrauen ?
Das Problem mit tar.gz
Archiven besteht nicht darin, dass Sie sie dekomprimieren müssen. Das Dekomprimieren ist oft schneller als das Ablesen einer Festplatte (Sie werden wahrscheinlich feststellen, dass das Auflisten des Inhalts eines großen TGZ-Archivs schneller ist als das Auflisten desselben unkomprimierten Archivs, wenn es nicht im Speicher zwischengespeichert ist), aber Sie müssen das gesamte Archiv lesen.
Es ist kein Problem, den Index nicht schnell lesen zu können. Wenn Sie den Tabelleninhalt eines Archivs häufig lesen müssen, können Sie diese Liste einfach in einer separaten Datei speichern. Zum Zeitpunkt der Erstellung können Sie beispielsweise Folgendes tun:
tar cvvf - dir 2> file.tar.xz.list | xz > file.tar.xz
Ein größeres Problem IMO ist die Tatsache, dass Sie aufgrund des sequentiellen Aspekts des Archivs keine einzelnen Dateien extrahieren können, ohne den gesamten Anfangsabschnitt des Archivs zu lesen, der dazu führt. IOW, Sie können keine zufälligen Lesevorgänge im Archiv durchführen.
Für durchsuchbare Dateien muss dies nicht mehr so sein.
Wenn Sie Ihr tar
Archiv mit gzip
komprimieren, wodurch es als Ganzes komprimiert wird, verwendet der Komprimierungsalgorithmus die zu Beginn angezeigten Daten zum Komprimieren. Sie müssen also von vorne beginnen, um die Komprimierung aufzuheben.
Das xz
Format kann jedoch so konfiguriert werden, dass Daten in separaten einzelnen Blöcken komprimiert werden (groß genug, um die Komprimierung effizient zu gestalten). Dies bedeutet, dass Sie für durchsuchbare Dateien auf den zugreifen können, solange Sie einen Index am Ende dieser komprimierten Blöcke behalten unkomprimierte Daten zufällig (mindestens in Blöcken).
pixz
(parallel xz
) verwendet diese Funktion beim Komprimieren von tar
Archiven, um auch einen Index des Starts jedes Mitglieds des Archivs am Ende der xz
Datei hinzuzufügen .
Bei durchsuchbaren Dateien können Sie also nicht nur sofort (ohne Metadaten) eine Liste des Inhalts des TAR-Archivs abrufen, wenn diese komprimiert wurden mit pixz
:
pixz -l file.tar.xz
Sie können aber auch einzelne Elemente extrahieren, ohne das gesamte Archiv lesen zu müssen:
pixz -x archive/member.txt < file.tar.xz | tar xpf -
Nun, warum Dinge wie 7z
oder zip
selten unter Unix verwendet werden, liegt hauptsächlich daran, dass sie Unix-Dateien nicht archivieren können. Sie wurden für andere Betriebssysteme entwickelt. Mit diesen können Sie keine zuverlässige Datensicherung durchführen. Sie können keine Metadaten wie Eigentümer (ID und Name), Berechtigung, Symlinks, Geräte, Fifos ..., keine Informationen zu festen Links und andere Metadaten wie erweiterte Attribute oder ACLs speichern.
Einige von ihnen können nicht einmal Mitglieder mit beliebigen Namen speichern (andere ersticken an Backslash oder Newline oder Doppelpunkt oder Nicht-ASCII-Dateinamen) (einige tar
Formate haben jedoch auch Einschränkungen).
Dekomprimieren Sie niemals eine tgz / tar.xz-Datei auf die Festplatte!
Falls es nicht offensichtlich ist, verwendet man kein tgz
oder tar.bz2
, tar.xz
... Archiv als:
unxz file.tar.xz
tar tvf file.tar
xz file.tar
Wenn Sie eine unkomprimierte .tar
Datei in Ihrem Dateisystem haben, haben Sie etwas falsch gemacht.
Der springende Punkt bei diesen xz
/ bzip2
/ gzip
Stream-Kompressoren ist, dass sie im laufenden Betrieb in Pipelines wie in verwendet werden können
unxz < file.tar.xz | tar tvf -
Obwohl moderne tar
Implementierungen wissen , wie aufrufen unxz
/ gunzip
/ bzip2
von selbst, so:
tar tvf file.tar.xz
würde im Allgemeinen auch funktionieren (und die Daten erneut im laufenden Betrieb dekomprimieren und die unkomprimierte Version des Archivs nicht auf der Festplatte speichern).
Beispiel
Hier ist ein Linux-Kernel-Quellbaum, der mit verschiedenen Formaten komprimiert ist.
$ ls --block-size=1 -sS1
666210304 linux-4.6.tar
173592576 linux-4.6.zip
97038336 linux-4.6.7z
89468928 linux-4.6.tar.xz
Erstens, wie oben erwähnt, unterscheiden sich die 7z- und Zip-Links geringfügig, da sie die wenigen Symlinks dort nicht speichern können und die meisten Metadaten fehlen.
Nun einige Zeitpunkte, um den Inhalt aufzulisten, nachdem die Systemcaches geleert wurden:
$ echo 3 | sudo tee /proc/sys/vm/drop_caches
3
$ time tar tvf linux-4.6.tar > /dev/null
tar tvf linux-4.6.tar > /dev/null 0.56s user 0.47s system 13% cpu 7.428 total
$ time tar tvf linux-4.6.tar.xz > /dev/null
tar tvf linux-4.6.tar.xz > /dev/null 8.10s user 0.52s system 118% cpu 7.297 total
$ time unzip -v linux-4.6.zip > /dev/null
unzip -v linux-4.6.zip > /dev/null 0.16s user 0.08s system 86% cpu 0.282 total
$ time 7z l linux-4.6.7z > /dev/null
7z l linux-4.6.7z > /dev/null 0.51s user 0.15s system 89% cpu 0.739 total
Sie werden feststellen, dass die Auflistung der tar.xz
Datei .tar
selbst auf diesem 7 Jahre alten PC schneller ist als die, da das Lesen dieser zusätzlichen Megabyte von der Festplatte länger dauert als das Lesen und Dekomprimieren der kleineren Datei.
OK, das Auflisten der Archive mit 7z oder zip ist schneller, aber das ist kein Problem, wie gesagt, es kann leicht umgangen werden, indem die Dateiliste neben dem Archiv gespeichert wird:
$ tar tvf linux-4.6.tar.xz | xz > linux-4.6.tar.xz.list.xz
$ ls --block-size=1 -sS1 linux-4.6.tar.xz.list.xz
434176 linux-4.6.tar.xz.list.xz
$ time xzcat linux-4.6.tar.xz.list.xz > /dev/null
xzcat linux-4.6.tar.xz.list.xz > /dev/null 0.05s user 0.00s system 99% cpu 0.051 total
Noch schneller als 7z oder Reißverschluss, selbst nachdem Caches gelöscht wurden. Sie werden auch feststellen, dass die kumulative Größe des Archivs und seines Index immer noch kleiner ist als die der Zip- oder 7z-Archive.
Oder verwenden Sie das pixz
indizierte Format:
$ xzcat linux-4.6.tar.xz | pixz -9 > linux-4.6.tar.pixz
$ ls --block-size=1 -sS1 linux-4.6.tar.pixz
89841664 linux-4.6.tar.pixz
$ echo 3 | sudo tee /proc/sys/vm/drop_caches
3
$ time pixz -l linux-4.6.tar.pixz > /dev/null
pixz -l linux-4.6.tar.pixz > /dev/null 0.04s user 0.01s system 57% cpu 0.087 total
Um nun einzelne Elemente des Archivs zu extrahieren, ist das Worst-Case-Szenario für ein Teerarchiv der Zugriff auf das letzte Element:
$ xzcat linux-4.6.tar.xz.list.xz|tail -1
-rw-rw-r-- root/root 5976 2016-05-15 23:43 linux-4.6/virt/lib/irqbypass.c
$ time tar xOf linux-4.6.tar.xz linux-4.6/virt/lib/irqbypass.c | wc
257 638 5976
tar xOf linux-4.6.tar.xz linux-4.6/virt/lib/irqbypass.c 7.27s user 1.13s system 115% cpu 7.279 total
wc 0.00s user 0.00s system 0% cpu 7.279 total
Das ist ziemlich schlecht, da es das gesamte Archiv lesen (und dekomprimieren) muss. Vergleichen mit:
$ time unzip -p linux-4.6.zip linux-4.6/virt/lib/irqbypass.c | wc
257 638 5976
unzip -p linux-4.6.zip linux-4.6/virt/lib/irqbypass.c 0.02s user 0.01s system 19% cpu 0.119 total
wc 0.00s user 0.00s system 1% cpu 0.119 total
Meine Version von 7z scheint keinen zufälligen Zugriff zu ermöglichen, daher scheint es noch schlimmer zu sein als tar.xz
:
$ time 7z e -so linux-4.6.7z linux-4.6/virt/lib/irqbypass.c 2> /dev/null | wc
257 638 5976
7z e -so linux-4.6.7z linux-4.6/virt/lib/irqbypass.c 2> /dev/null 7.28s user 0.12s system 89% cpu 8.300 total
wc 0.00s user 0.00s system 0% cpu 8.299 total
Jetzt, da wir unsere pixz
von früher generierte haben:
$ time pixz < linux-4.6.tar.pixz -x linux-4.6/virt/lib/irqbypass.c | tar xOf - | wc
257 638 5976
pixz -x linux-4.6/virt/lib/irqbypass.c < linux-4.6.tar.pixz 1.37s user 0.06s system 84% cpu 1.687 total
tar xOf - 0.00s user 0.01s system 0% cpu 1.693 total
wc 0.00s user 0.00s system 0% cpu 1.688 total
Es ist schneller, aber immer noch relativ langsam, da das Archiv nur wenige große Blöcke enthält:
$ pixz -tl linux-4.6.tar.pixz
17648865 / 134217728
15407945 / 134217728
18275381 / 134217728
19674475 / 134217728
18493914 / 129333248
336945 / 2958887
Es muss also pixz
noch ein (bis zu) ~ 19 MB großer Datenblock gelesen und dekomprimiert werden.
Wir können den Direktzugriff beschleunigen, indem wir Archive kleiner machen (und ein wenig Speicherplatz opfern):
$ pixz -f0.25 -9 < linux-4.6.tar > linux-4.6.tar.pixz2
$ ls --block-size=1 -sS1 linux-4.6.tar.pixz2
93745152 linux-4.6.tar.pixz2
$ time pixz < linux-4.6.tar.pixz2 -x linux-4.6/virt/lib/irqbypass.c | tar xOf - | wc
257 638 5976
pixz -x linux-4.6/virt/lib/irqbypass.c < linux-4.6.tar.pixz2 0.17s user 0.02s system 98% cpu 0.189 total
tar xOf - 0.00s user 0.00s system 1% cpu 0.188 total
wc 0.00s user 0.00s system 0% cpu 0.187 total