GNU/Linux >> Linux の 問題 >  >> Linux

Unzipはアーカイブ内の単一のファイルを見つけるためにどのような方法を使用しますか?

それぞれ30MBのサイズのランダムなテキストデータを使用して100個のファイルを作成するとします。次に、圧縮率が0のzipアーカイブを作成します。つまり、zip dataset.zip -r -0 *.txt 。ここで、このアーカイブから1つのファイルだけを抽出したいと思います。

ここで説明するように、アーカイブからファイルを解凍/抽出するには2つの方法があります。

  1. ファイルの最後を探し、中央ディレクトリを検索します。次に、それを使用して、抽出するファイルに高速でランダムアクセスします。(償却済みO(1) 複雑さ)
  2. 各ローカルヘッダーを調べて、一致するヘッダーを抽出します。(O(n) 複雑さ)

unzipはどの方法を使用しますか?私の実験から、それは方法2を使用しているように見えますか?

承認された回答:

大規模なアーカイブで単一のファイルを検索する場合は、方法1を使用します。これは、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 dataset.zipを開きます 、最後までシークし、次にアーカイブ内の要求されたファイルの先頭までシークします(rand-28.txt 、オフセット849346560で)、そこから読み取ります。

中央ディレクトリは、アーカイブの最後の65557バイトをスキャンすることによって検出されます。ここから始まるコードを参照してください:

/*---------------------------------------------------------------------------
    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. Linuxコマンドが何をするかを知る方法

  2. Bash:Find Into Selectの空白に安全な手続き上の使用?

  3. Exec 3とは何ですか?

  1. テキストファイルの行末を見つける方法は?

  2. .pid ファイルとは何ですか? また、何が含まれていますか?

  3. 使用中のファイルを移動 -- どのように機能するのか?

  1. Linuxのスティッキービット、SUID、SGIDとは

  2. .bashrcの「rc」は何の略ですか?

  3. 単一のファイルを複数の場所にscpします