GNU/Linux >> Belajar Linux >  >> Linux

Metode Apa yang Digunakan Unzip Untuk Menemukan Satu File Dalam Arsip?

Katakanlah saya membuat 100 file dengan data teks acak masing-masing berukuran 30MB. Sekarang saya membuat arsip zip dengan kompresi 0 yaitu zip dataset.zip -r -0 *.txt . Sekarang saya ingin mengekstrak hanya satu file dari arsip ini.

Seperti yang dijelaskan di sini, ada dua cara untuk membuka ritsleting/mengekstrak file dari arsip:

  1. Cari ke akhir file dan cari direktori pusat. Kemudian gunakan itu untuk akses acak cepat ke file yang akan diekstraksi.(Diamortisasi O(1) kompleksitas)
  2. Lihat setiap header lokal dan ekstrak header yang cocok.(O(n) kompleksitas)

Metode apa yang digunakan unzip? Dari percobaan saya sepertinya menggunakan metode 2?

Jawaban yang Diterima:

Saat mencari satu file dalam arsip besar, metode ini menggunakan metode 1, yang dapat Anda lihat menggunakan strace :

open("dataset.zip", O_RDONLY)           = 3
ioctl(1, TIOCGWINSZ, 0x7fff9a895920)    = -1 ENOTTY (Inappropriate ioctl for device)
write(1, "Archive:  dataset.zip\n", 22Archive:  dataset.zip
) = 22
lseek(3, 943718400, SEEK_SET)           = 943718400
read(3, "\340P\356(s\342\306\205\201\27\360U[\250/2\207\346<\252+u\234\225\1[<\2310E\342\274"..., 4522) = 4522
lseek(3, 943722880, SEEK_SET)           = 943722880
read(3, "\3\f\225P\\ux\v\0\1\4\350\3\0\0\4\350\3\0\0", 20) = 20
lseek(3, 943718400, SEEK_SET)           = 943718400
read(3, "\340P\356(s\342\306\205\201\27\360U[\250/2\207\346<\252+u\234\225\1[<\2310E\342\274"..., 8192) = 4522
lseek(3, 849346560, SEEK_SET)           = 849346560
read(3, "D\262nv\210\343\240C\24\227\344\367q\300\223\231\306\330\275\266\213\276M\7I'&35\2\234J"..., 8192) = 8192
stat("rand-28.txt", 0x559f43e0a550)     = -1 ENOENT (No such file or directory)
lstat("rand-28.txt", 0x559f43e0a550)    = -1 ENOENT (No such file or directory)
stat("rand-28.txt", 0x559f43e0a550)     = -1 ENOENT (No such file or directory)
lstat("rand-28.txt", 0x559f43e0a550)    = -1 ENOENT (No such file or directory)
open("rand-28.txt", O_RDWR|O_CREAT|O_TRUNC, 0666) = 4
ioctl(1, TIOCGWINSZ, 0x7fff9a895790)    = -1 ENOTTY (Inappropriate ioctl for device)
write(1, " extracting: rand-28.txt        "..., 37 extracting: rand-28.txt             ) = 37
read(3, "\275\3279Y\206\223\217}\355W%:\220YNT\0\257\260z^\361T\242\2\370\21\336\372+\306\310"..., 8192) = 8192

unzip buka dataset.zip , mencari sampai akhir, lalu mencari ke awal file yang diminta dalam arsip (rand-28.txt , pada offset 849346560) dan membaca dari sana.

Direktori pusat ditemukan dengan memindai 65557 byte terakhir dari arsip; lihat kode mulai dari sini:

/*---------------------------------------------------------------------------
    Find and process the end-of-central-directory header.  UnZip need only
    check last 65557 bytes of zipfile:  comment may be up to 65535, end-of-
    central-directory record is 18 bytes, and signature itself is 4 bytes;
    add some to allow for appended garbage.  Since ZipInfo is often used as
    a debugging tool, search the whole zipfile if zipinfo_mode is true.
  ---------------------------------------------------------------------------*/

Linux
  1. Apa cara yang tepat untuk menggunakan inotify?

  2. Apa itu file .pid dan apa isinya?

  3. Bagaimana rm bekerja? Apa yang rm lakukan?

  1. Apa itu `S_ISREG()`, dan apa fungsinya?

  2. Apa arti 'rc' di `.bashrc`, dll.?

  3. Memindahkan File Saat Sedang Digunakan -- Bagaimana cara kerjanya?

  1. Bagaimana cara mengetahui apa yang dilakukan perintah Linux

  2. Bash:Penggunaan Prosedural Find Into Select yang aman-spasi?

  3. scp satu file ke beberapa lokasi