GNU/Linux >> Tutoriales Linux >  >> Linux

¿Qué método utiliza Descomprimir para encontrar un solo archivo en un archivo?

Digamos que creo 100 archivos con datos de texto aleatorios de 30 MB cada uno. Ahora creo un archivo zip con compresión 0, es decir, zip dataset.zip -r -0 *.txt . Ahora quiero extraer solo un archivo de este archivo.

Como se describe aquí, hay dos formas de descomprimir/extraer archivos de archivos comprimidos:

  1. Busque hasta el final del archivo y busque en el directorio central. Luego, utilícelo para un acceso aleatorio rápido al archivo que se va a extraer. (Amortized O(1) complejidad)
  2. Revise cada encabezado local y extraiga el que coincida.(O(n) complejidad)

¿Qué método utiliza el descompresor? Según mis experimentos, ¿parece que usa el método 2?

Respuesta aceptada:

Cuando busca un solo archivo en un archivo grande, usa el método 1, que puede ver usando 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 abre dataset.zip , busca hasta el final, luego busca el inicio del archivo solicitado en el archivo (rand-28.txt , en el desplazamiento 849346560) y lee desde allí.

El directorio central se encuentra escaneando los últimos 65557 bytes del archivo; mira el código que comienza aquí:

/*---------------------------------------------------------------------------
    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. ¿Cómo saber los finales de línea en un archivo de texto?

  2. ¿Cuál es la forma correcta de usar inotify?

  3. ¿Qué es `S_ISREG()` y qué hace?

  4. Mover un archivo mientras está en uso:¿cómo funciona?

  5. extraer un solo archivo de un archivo tgz enorme

Comando de archivo de Linux:qué hace y cómo usarlo

Qué es EFS (Elastic File System) en AWS y cómo usarlo

ExpliqueShell:encuentre lo que hace cada parte de un comando de Linux

Cómo averiguar qué hace un comando de Linux

Bash:¿Uso de procedimiento seguro para espacios en blanco de Find Into Select?

Cómo usar Sed para buscar y reemplazar una cadena en un archivo