Cetak daftar file arsip secara instan (tanpa mendekompresi seluruh arsip)

10

Masalah dengan .tar.gzarsip adalah bahwa, ketika saya mencoba hanya daftar konten arsip, komputer benar-benar mendekompresinya, yang akan memakan waktu sangat lama jika file tersebut besar.

Format file lain seperti .7z, .rar, .ziptidak memiliki masalah ini. Mendaftarkan konten mereka hanya perlu sesaat.

Menurut pendapat saya yang naif, ini adalah kelemahan besar dari .tar.gzformat arsip.

Jadi saya sebenarnya punya 2 pertanyaan:

  1. mengapa orang menggunakan .tar.gzbegitu banyak, meskipun ada kelemahan ini?
  2. pilihan apa (maksud saya perangkat lunak atau alat lain) yang saya miliki jika saya ingin kemampuan "daftar isi instan"?
Dave
sumber
Kemungkinan duplikat dari [ superuser.com/questions/565883/… .
agc
Gunzip dulu?
Jeff Schaller

Jawaban:

18

Sangat penting untuk memahami ada pertukaran di sini.

tarberarti tape archiver . Pada kaset, Anda kebanyakan membaca dan menulis berurutan. Kaset jarang digunakan saat ini, tetapi tarmasih digunakan untuk kemampuannya membaca dan menulis datanya sebagai streaming.

Anda dapat melakukan:

tar cf - files | gzip | ssh host 'cd dest && gunzip | tar xf -'

Anda tidak dapat melakukannya dengan zipatau sejenisnya.

Anda bahkan tidak dapat membuat daftar konten ziparsip tanpa menyimpannya secara lokal di file yang dapat dicari terlebih dahulu. Berpikir seperti:

curl -s https://github.com/dwp-forge/columns/archive/v.2016-02-27.zip | unzip -l /dev/stdin

tidak akan bekerja

Untuk mencapai pembacaan cepat konten, zipatau sejenisnya perlu membuat indeks. Indeks itu dapat disimpan di awal file (dalam hal ini hanya dapat ditulis ke file biasa, bukan stream), atau pada akhirnya, yang berarti pengarsip perlu mengingat semua anggota arsip sebelum mencetaknya pada akhirnya dan berarti arsip yang terpotong mungkin tidak dapat dipulihkan.

Itu juga berarti anggota arsip perlu dikompresi secara individual yang berarti rasio kompresi yang jauh lebih rendah terutama jika ada banyak file kecil.

Kelemahan lain dengan format seperti zipadalah bahwa pengarsipan terkait dengan kompresi, Anda tidak dapat memilih algoritma kompresi. Lihat bagaimana tararsip digunakan untuk dikompresi dengan compress( tar.Z), kemudian dengan gzip, kemudian bzip2, kemudian xzsebagai algoritma kompresi baru yang lebih performan dirancang. Sama berlaku untuk enkripsi. Siapa yang akan mempercayai zipenkripsi saat ini?

Sekarang, masalah dengan tar.gzarsip tidak sebanyak yang Anda butuhkan untuk mengompresnya. Mengompres seringkali lebih cepat daripada membaca disk (Anda mungkin akan menemukan bahwa mendaftar konten arsip tgz besar lebih cepat daripada mendaftar yang sama tanpa terkompresi ketika tidak di-cache dalam memori), tetapi Anda harus membaca seluruh arsip.

Tidak bisa membaca indeks dengan cepat bukanlah masalah. Jika Anda melihat perlu sering membaca isi tabel arsip, Anda bisa menyimpan daftar itu dalam file terpisah. Misalnya, pada waktu pembuatan, Anda dapat melakukan:

tar cvvf - dir 2> file.tar.xz.list | xz > file.tar.xz

Masalah IMO yang lebih besar adalah kenyataan bahwa karena aspek berurutan dari arsip, Anda tidak dapat mengekstrak file individual tanpa membaca seluruh bagian awal dari arsip yang mengarah padanya. TKI, Anda tidak dapat melakukan pembacaan acak dalam arsip.

Sekarang, untuk file yang dapat dicari, tidak harus seperti itu.

Jika Anda mengompres tararsip Anda dengan gzip, yang kompres itu secara keseluruhan, algoritma kompresi menggunakan data yang terlihat di awal untuk kompres, jadi Anda harus mulai dari awal hingga membuka kompres.

Tetapi xzformat dapat dikonfigurasikan untuk mengompresi data dalam potongan individual yang terpisah (cukup besar sehingga kompresi menjadi efisien), itu berarti bahwa selama Anda menyimpan indeks di akhir potongan terkompresi itu, untuk file yang dapat dicari, Anda mengakses data yang tidak terkompresi secara acak (setidaknya dalam chunks).

pixz(paralel xz) menggunakan kemampuan itu saat mengompresi tararsip untuk juga menambahkan indeks awal setiap anggota arsip di akhir xzfile.

Jadi, untuk file yang dapat dicari, Anda tidak hanya bisa mendapatkan daftar isi arsip tar secara instan (tanpa metadata) jika mereka telah dikompres dengan pixz:

pixz -l file.tar.xz

Tetapi Anda juga dapat mengekstrak elemen individual tanpa harus membaca seluruh arsip:

pixz -x archive/member.txt < file.tar.xz | tar xpf -

Sekarang, mengapa hal-hal seperti 7zatau zipjarang digunakan di Unix sebagian besar karena mereka tidak dapat mengarsipkan file Unix. Mereka telah dirancang untuk sistem operasi lain. Anda tidak dapat melakukan pencadangan data yang benar dengan menggunakan itu. Mereka tidak dapat menyimpan metadata seperti pemilik (id dan nama), izin, mereka tidak dapat menyimpan symlink, perangkat, fifos ..., mereka tidak dapat menyimpan informasi tentang tautan keras, dan informasi metadata lainnya seperti atribut yang diperluas atau ACL.

Beberapa dari mereka bahkan tidak dapat menyimpan anggota dengan nama sewenang-wenang (beberapa akan tersedak backslash atau baris baru atau titik dua, atau nama file non-ascii) (beberapa tarformat juga memiliki batasan).

Jangan pernah mengompres file tgz / tar.xz ke disk!

Jika tidak jelas, seseorang tidak menggunakan arsip tgzatau tar.bz2, tar.xz... sebagai:

unxz file.tar.xz
tar tvf file.tar
xz file.tar

Jika Anda memiliki .tarfile terkompresi yang berbohong pada sistem file Anda, itu karena Anda melakukan kesalahan.

Inti dari mereka xz/ bzip2/ gzipmenjadi kompresor aliran adalah bahwa mereka dapat digunakan dengan cepat, dalam pipa seperti pada

unxz < file.tar.xz | tar tvf -

Meskipun tarimplementasi modern tahu bagaimana memohon unxz/ gunzip/ bzip2sendiri, jadi:

tar tvf file.tar.xz

umumnya juga akan berfungsi (dan sekali lagi tidak mengompres data dengan cepat dan tidak menyimpan versi terkompresi dari arsip pada disk).

Contoh

Berikut pohon sumber kernel Linux yang dikompresi dengan berbagai format.

$ 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

Pertama, seperti disebutkan di atas, 7z dan zip sedikit berbeda karena mereka tidak dapat menyimpan beberapa symlink di sana dan kehilangan sebagian besar metadata.

Sekarang beberapa timing untuk mendaftar konten setelah mem-flush cache sistem:

$ 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

Anda akan melihat daftar tar.xzfile lebih cepat daripada yang .tarbahkan pada PC berusia 7 tahun ini karena membaca megabita ekstra dari disk membutuhkan waktu lebih lama daripada membaca dan mendekompresi file yang lebih kecil.

Kemudian OK, mendaftar arsip dengan 7z atau zip lebih cepat tapi itu bukan masalah seperti yang saya katakan, itu mudah dikerjakan dengan menyimpan daftar file di samping arsip:

$ 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

Bahkan lebih cepat dari 7z atau zip bahkan setelah menjatuhkan cache. Anda juga akan melihat bahwa ukuran kumulatif arsip dan indeksnya masih lebih kecil dari arsip zip atau 7z.

Atau gunakan pixzformat yang diindeks:

$ 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

Sekarang, untuk mengekstraksi masing-masing elemen arsip, skenario kasus terburuk untuk arsip tar adalah ketika mengakses elemen terakhir:

$ 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

Itu sangat buruk karena perlu membaca (dan membuka kompresi) seluruh arsip. Dibandingkan dengan:

$ 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

Versi 7z saya tampaknya tidak dapat melakukan akses acak, jadi sepertinya lebih buruk daripada 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

Sekarang karena kami telah pixzmenghasilkan yang dari sebelumnya:

$ 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

Lebih cepat tetapi masih relatif lambat karena arsip berisi beberapa blok besar:

$ pixz -tl linux-4.6.tar.pixz
 17648865 / 134217728
 15407945 / 134217728
 18275381 / 134217728
 19674475 / 134217728
 18493914 / 129333248
   336945 /   2958887

Jadi pixzmasih perlu membaca dan membuka kompresi (hingga a) ~ 19MB sepotong besar data.

Kita dapat membuat akses acak lebih cepat dengan membuat arsip akan memblokir lebih kecil (dan mengorbankan sedikit ruang disk):

$ 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
Stéphane Chazelas
sumber
"Tidak bisa membaca indeks dengan cepat bukanlah masalah." Sebaliknya, itu adalah show-stopper ketika tidak ada cukup ruang atau waktu untuk bahkan mengompres file. Sarankan: 's / Tidak / Kadang-kadang tidak /'
agc
1
@ Agc, baca edit dengan beberapa bagian tambahan. Semoga itu menjelaskannya. Anda tentu tidak membutuhkan ruang disk tambahan untuk mendaftar konten arsip.
Stéphane Chazelas
1
Tolong maafkan saya SC, penambahan Anda diambil dengan baik, (terutama mengenai ruang disk dan daftar arsip), tapi saya sebagian besar berarti kata penghubung atau inklusif "atau" di sini: "tidak cukup ruang atau waktu" - yaitu set yang terdiri dari keduanya , satu atau yang lain. Terkadang situasi membuat pengguna tidak siap, dan tanpa persiapan yang Anda jelaskan sebelumnya, masalah besar .tar.gzbisa memakan waktu terlalu lama. Apalagi jika medianya lambat. Saat itulah format arsip menjadi perbedaan antara yang mustahil dan praktis.
agc
@ StéphaneChazelas: jawaban Anda bagus dan komprehensif, tapi saya pikir Anda harus mengedit bagian tentang pixz - sepertinya proyek ini jarang dipelihara dan memiliki banyak masalah, jadi sebaiknya tidak digunakan untuk membuat cadangan data penting, di saya pendapat.
Maksim
3
  1. mengapa banyak orang menggunakannya meskipun ada kekurangan ini?

Admin Korporat dan Akademik sering kali lebih diperhatikan ketika sesuatu pecah, daripada dihargai ketika segalanya berjalan efisien. Lingkungan seperti itu menumbuhkan rasa takut akan eksperimen, dan mencemooh kebaruan .

  1. pilihan apa (maksud saya perangkat lunak / alat lain) yang saya miliki jika saya ingin kemampuan "daftar isi instan"?

dar ( D isiko Ar chiver) dilengkapi dengan rakit tar -seperti fitur, ditambah perangkat tambahan seperti akses speedy acak untuk arsip dikompresi, AKA katalog, AKA pengindeksan, AKA "konten instan daftar" ...

Lihat juga: Format kompresi dengan dukungan yang baik untuk akses acak di dalam arsip?

agc
sumber