GNU/Linux >> Tutoriels Linux >  >> Linux

Quelle méthode utilise Unzip pour trouver un seul fichier dans une archive ?

Disons que je crée 100 fichiers avec des données texte aléatoires de 30 Mo chacun. Maintenant, je crée une archive zip avec 0 compression, c'est-à-dire zip dataset.zip -r -0 *.txt . Maintenant, je veux extraire un seul fichier de cette archive.

Comme décrit ici, il existe deux manières de décompresser/extraire des fichiers d'archives :

  1. Allez jusqu'à la fin du fichier et recherchez le répertoire central. Utilisez-le ensuite pour un accès aléatoire rapide au fichier à extraire.(Amortized O(1) complexité)
  2. Parcourez chaque en-tête local et extrayez celui où il y a une correspondance.(O(n) complexité)

Quelle méthode utilise unzip ? D'après mes expériences, il semble qu'il utilise la méthode 2 ?

Réponse acceptée :

Lors de la recherche d'un seul fichier dans une grande archive, il utilise la méthode 1, que vous pouvez voir en utilisant 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 ouvre dataset.zip , cherche jusqu'à la fin, puis cherche jusqu'au début du fichier demandé dans l'archive (rand-28.txt , au décalage 849346560) et lit à partir de là.

Le répertoire central est trouvé en parcourant les 65557 derniers octets de l'archive; voir le code à partir d'ici :

/*---------------------------------------------------------------------------
    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. Quelle est la bonne façon d'utiliser inotify ?

  2. Comment ça marche ? Que fait rm ?

  3. Qu'est-ce que `S_ISREG()` et à quoi sert-il ?

  4. Que signifie le « rc » dans « .bashrc », etc. ?

  5. Déplacer un fichier en cours d'utilisation -- Comment ça marche ?

Commande de fichier Linux :que fait-elle et comment l'utiliser

Qu'est-ce qu'EFS (Elastic File System) dans AWS et comment l'utiliser

ExplainShell - Trouvez ce que fait chaque partie d'une commande Linux

Comment utiliser Sed pour rechercher et remplacer une chaîne dans un fichier

Qu'est-ce qu'un fichier .pid et que contient-il ?

scp un seul fichier vers plusieurs emplacements