Вы можете попробовать Archlinux с Linux LTS 3.10.XX-X , который основан на версии Linux 3.10 LTS из ядра .org .
Archlinux по умолчанию поставляется с последним стабильным ядром, которое на данный момент - 3.12.9-2, но установить LTS-версию довольно просто, поскольку она находится в официальных репозиториях Archlinux.
Чтобы установить его и сгенерировать запись grub, выполните:
$ pacman -S linux-lts
$ grub-mkconfig -o /boot/grub/grub.cfg
При поиске одного файла в большом архиве используется метод 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.
---------------------------------------------------------------------------*/
На самом деле это смесь. unzip считывает некоторые данные из известного расположения, а затем считывает блоки данных, относящиеся к (, но не идентичные )целевой записи в zip-файле -.
Структура zip/unzip объясняется в комментариях к исходным -файлам. Вот соответствующий изextract.c
:
/*---------------------------------------------------------------------------
The basic idea of this function is as follows. Since the central di-
rectory lies at the end of the zipfile and the member files lie at the
beginning or middle or wherever, it is not very desirable to simply
read a central directory entry, jump to the member and extract it, and
then jump back to the central directory. In the case of a large zipfile
this would lead to a whole lot of disk-grinding, especially if each mem-
ber file is small. Instead, we read from the central directory the per-
tinent information for a block of files, then go extract/test the whole
block. Thus this routine contains two small(er) loops within a very
large outer loop: the first of the small ones reads a block of files
from the central directory; the second extracts or tests each file; and
the outer one loops over blocks. There's some file-pointer positioning
stuff in between, but that's about it. Btw, it's because of this jump-
ing around that we can afford to be lenient if an error occurs in one of
the member files: we should still be able to go find the other members,
since we know the offset of each from the beginning of the zipfile.
---------------------------------------------------------------------------*/
Сам формат в основном заимствован из реализации PK -Ware и кратко изложен в текстовых -файлах информации о программировании . В соответствии с этим в центральном каталоге также есть несколько типов записей, поэтому unzip не может легко перейти к концу файла и создать массив записей для поиска целевого файла.
Теперь... если вы потратите время на чтение исходного кода, вы обнаружите, чтоunzip
читает буферы размером 8192 байта (ищетINBUFSIZ
).Я бы использовал один файл -только для довольно большого zip-файла (. Я имел в виду исходники Java ), но даже для меньшего zip-файла -вы можете увидеть эффект размер буфера. Чтобы увидеть это, я заархивировал файлы Git для PuTTY, что дало 2727 файлов (, считая копию журнала git ). Java был больше, чем 20 лет назад, и не уменьшился. Извлечение этого журнала из zip -файла (, выбранного, поскольку он не будет находиться в конце индекса, отсортированного по алфавиту -, и, вероятно,нев первом блоке, считанном из центрального каталога )дал это отstrace
для lseek
вызовов:
lseek(3, -2252, SEEK_CUR) = 1267
lseek(3, 120463360, SEEK_SET) = 120463360
lseek(3, 120468731, SEEK_SET) = 120468731
lseek(3, 120135680, SEEK_SET) = 120135680
lseek(3, 270336, SEEK_SET) = 270336
lseek(3, 120463360, SEEK_SET) = 120463360
Как обычно, с бенчмаркамиymmv.