Вопрос по decompression, 7zip, wikipedia, random-access, compression – случайный поиск в одном файловом архиве 7z

2

Можно ли сделать произвольный доступ (много поисков) к очень огромному файлу, сжатому 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 МБ / с (из распакованных данных), используется только одно ядро ЦП.

Есть также интересный вариантxzВасиpixz, который может упаковать файлы в несколько блоков и добавить индекс потоков для быстрого поиска (обычно для быстрого поиска вtar.xz):github.com/vasi/pixz "Вместо этого Pixz создает коллекцию меньших блоков, что делает возможным произвольный доступ к исходным данным. Это особенно полезно для больших тарболлов." osgx

Ваш Ответ

4   ответа
0

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

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

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

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

Привет. Это сделает полную распаковку (или распаковку до SIGPIPE для самого начала), и Мой архив очень-очень большой, 999 гигабайт в распакованном размере текста (средняя длина строки 20 или 30 символов utf-8). Иногда я хочу строку 7, иногда строки 10245-10345, иногда строки 21453361643-21453361720. Когда я просто хочу 1 миллион строк ближе к концу архива, я не хочу распаковывать все 20000 миллионов строк раньше (это займет полчаса). Некоторые форматы архивов поддерживают индексирование, чтобы разрешить такой доступ (создать индекс один раз и использовать его для быстрого доступа). osgx
2

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

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

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

7zip не «чанки» входного файла, так что это один блок, сжатый по методике «скользящего окна». Проблема, с которой вы столкнетесь, заключается в том, что 7zip получил отличную степень сжатияпотому что он сжал ваш файл как один блок. Если бы вам пришлось разрезать файл на маленькие блоки и сжать их один за другим с помощью 7zip, вы бы не получили тот же результат. К сожалению, единственный способ получить прямой доступ к любой части вашего файла - это сначала разрезать его на маленькие блоки. Отсюда и дилемна ... Cyan
lz4demo означает, что мне нужно перепаковать полный огромный файл? Уровень сжатия lz4 того же порядка, что и 7zip? Этот огромный файл упакован в 7zip / lzma / xz, потому что он слишком большой; даже в bz2 это не 4 ГБ, а 14 ГБ. Можете ли вы сказать что-нибудь о размере блока, использованном в моем заголовке файла? osgx
1

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

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

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

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

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

Только что проверил. Мой файл имеет один блок. Как я могу найти размер словаря, используемого для сжатия из архива? Использование памяти 7zfm при тестировании составило 25 МБ. osgx
ММЧ 1 мин исследования показывают, что свойство LZMA заключается в том, что он поддерживает очень большие словари (> 1 ГБ), так что это действительно может быть один связный блок. sleeplessnerd
sleeplessnerd, вопрос здесь такой: «В этом архиве 7z много блоков или только один блок?». Я предлагаю это только один блок. osgx
0

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

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

Исходный файл очень большой (999 ГБ xml)

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

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

Статьи, шаблоны, описания мультимедиа / файлов и основные мета-страницы, в нескольких потоках 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 с правильным диапазоном (..pfirst_id p last_id .7z).stub-meta-history.xml может помочь тоже.

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

Похожие вопросы