Случайный поиск в одном файловом архиве 7z

Можно ли сделать произвольный доступ (много поисков) к очень огромному файлу, сжатому 7zip?

Исходный файл очень большой (999 ГБ xml), и я не могу сохранить его в распакованном формате (у меня не так много свободного места). Итак, если формат 7z позволяет получить доступ к среднему блоку, не распаковывая все блоки перед выбранным, я могу построить индекс начала блока и соответствующие исходные смещения файла.

Заголовок моего 7z архива есть

37 7A BC AF 27 1C 00 02 28 99 F1 9D 4A 46 D7 EA  // 7z archive version 2;crc; n.hfr offset
00 00 00 00 44 00 00 00 00 00 00 00 F4 56 CF 92  // n.hdr offset; n.hdr size=44. crc
00 1E 1B 48 A6 5B 0A 5A 5D DF 57 D8 58 1E E1 5F
71 BB C0 2D BD BF 5A 7C A2 B1 C7 AA B8 D0 F5 26
FD 09 33 6C 05 1E DF 71 C6 C5 BD C0 04 3A B6 29

ОБНОВЛЕНИЕ: архиватор 7z сообщает, что этот файл содержит один блок данных, сжатый по алгоритму LZMA. Скорость распаковки при тестировании составляет 600 МБ / с (из распакованных данных), используется только одно ядро ​​ЦП.

3 ответа

Это технически возможно, но если ваш вопрос "позволяет ли это доступный в настоящее время двоичный инструмент командной строки 7zip", ответ, к сожалению, нет. Лучшее, что он позволяет, - это независимое сжатие каждого файла в архив, что позволяет непосредственно извлекать файлы. Но так как вы хотите сжать один (огромный) файл, этот трюк не сработает.

Боюсь, единственный способ состоит в том, чтобы разбить ваш файл на маленькие блоки и передать их в кодировщик LZMA (входит в LZMA SDK). К сожалению, это требует некоторых навыков программирования.

Примечание: технически неполноценный, но тривиальный алгоритм сжатия можно найти здесь. Основная программа делает именно то, что вам нужно: разрезать исходный файл на маленькие блоки и подавать их один за другим в компрессор (в данном случае, LZ4). Затем декодер выполняет обратную операцию. Он может легко пропустить все сжатые блоки и перейти прямо к тому, который вы хотите получить. http://code.google.com/p/lz4/source/browse/trunk/lz4demo.c

Как насчет этого:

Концепция: поскольку вы в основном читаете только один файл, индексируйте.7z по блокам.

читать сжатый файл блок за блоком, давать каждому блоку номер и, возможно, смещение в большом файле. сканировать привязки целевых элементов в потоке данных (например, заголовки статей в Википедии). Для каждой записи привязки сохраните номер блока, с которого начался элемент (возможно, ранее он был в блоке)

запишите индекс в какое-то хранилище O(log n). Для доступа извлеките номер блока и его смещение, извлеките блок и найдите элемент. стоимость связана с извлечением одного блока (или очень немногих) и поиском строки в этом блоке.

для этого вам нужно прочитать файл один раз, но вы можете передать его и выбросить после обработки, чтобы ничто не попало на диск.

ДАРН: Вы в основном постулировали это в своем вопросе... кажется, что лучше прочитать вопрос, прежде чем отвечать...

Используйте только:

7z e myfile_xml.7z -so | sed [something] 

Пример получения строки 7:

7z e myfile_xml.7z -so | sed -n 7p

Архиватор 7z сообщает, что этот файл содержит один блок данных, сжатый по алгоритму LZMA.

Что за команда 7z / xz нашла, это один сжатый блок или нет? Будет ли 7z создавать многоблочный (многопоточный) архив при использовании с несколькими потоками?

Оригинальный файл очень большой (999 ГБ xml)

Хорошие новости: Википедия перешла на многопотоковые архивы для своих дампов (по крайней мере, для enwiki): http://dumps.wikimedia.org/enwiki/

Например, в самом последнем дампе http://dumps.wikimedia.org/enwiki/20140502/ имеется многопоточный bzip2 (с отдельным индексом "offset:export_article_id:article_name"), а дамп 7z хранится во многих архивах sub-GB с ~3 тыс. (?) Статей в архиве:

Статьи, шаблоны, описания мультимедиа / файлов и основные мета-страницы, в нескольких потоках bz2, 100 страниц на поток

enwiki-20140502-pages-articles-multistream.xml.bz2 10.8 GB
enwiki-20140502-pages-articles-multistream-index.txt.bz2 150.3 MB

Все страницы с полной историей редактирования (.7z)

enwiki-20140502-pages-meta-history1.xml-p000000010p000003263.7z 213.3 MB
enwiki-20140502-pages-meta-history1.xml-p000003264p000005405.7z 194.5 MB
enwiki-20140502-pages-meta-history1.xml-p000005406p000008209.7z 216.1 MB
enwiki-20140502-pages-meta-history1.xml-p000008210p000010000.7z 158.3 MB
enwiki-20140502-pages-meta-history2.xml-p000010001p000012717.7z 211.7 MB
 .....
enwiki-20140502-pages-meta-history27.xml-p041211418p042648840.7z 808.6 MB

Я думаю, мы можем использовать индекс bzip2 для оценки идентификатора статьи даже для дампов 7z, а затем нам просто нужен архив 7z с правильным диапазоном (..p first_id p last_id.7z). stub-meta-history.xml может помочь тоже.

FAQ по дампам: http://meta.wikimedia.org/wiki/Data_dumps/FAQ

Другие вопросы по тегам