Индексированная библиотека сжатия - PullRequest
1 голос
/ 02 августа 2011

Я работаю с системой, которая сжимает большие файлы (40 ГБ) и затем сохраняет их в архиве.

В настоящее время я использую libz.a для сжатия файлов с помощью C ++, но когда я хочу извлечь данные из файла, мне нужно извлечь все это. Кто-нибудь знает компонент сжатия (предпочтительно совместимый с .NET), который может хранить индекс исходных позиций файла, а затем, вместо распаковки всего файла, искать то, что нужно?

Пример:

Original File       Compressed File
10 - 27         =>  2-5
100-202         =>  10-19
..............
10230-102020    =>  217-298

Поскольку я знаю, что данные, которые мне нужны в файле, появляются только в исходном файле между позициями 10-27, я хотел бы отобразить исходные позиции в файлах в позиции сжатых файлов.

Кто-нибудь знает библиотеку сжатия или аналогичный легкодоступный инструмент, который может предложить эту функцию?

1 Ответ

1 голос
/ 03 августа 2011

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

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

Решение, которое я нашел, работает лучше всего, хотя оно уменьшает вашу степень сжатия - это упаковывать данные в куски. В моем проекте это было просто - каждая статья была 1 чанком, и я сжал их 1 на 1, а затем создал индексный файл, который сохранял то место, с которого начинается каждый «чанк», в этом случае распаковка была простой - просто распаковывал весь поток, который был одним статья, которую я хотел.

Итак, мой файл выглядел так:

Index; compress(A1); compress(A2); compress(A3)

вместо

compress(A1;A2;A3).

Если вы не можете разделить данные таким элегантным способом, вы всегда можете попробовать искусственно разделить порции, например, упаковать данные в порции по 5 МБ. Поэтому, когда вам нужно будет прочитать данные с 7 МБ до 13 МБ, вы просто распакуете фрагменты 5-10 и 10-15. Ваш индексный файл будет выглядеть так:

0     -> 0
5MB   -> sizeof(compress 5MB)
10MB  -> sizeof(compress 5MB) + sizeof(compress next 5MB)

Проблема этого решения в том, что оно дает немного худшую степень сжатия. Чем меньше куски - тем хуже будет сжатие.

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

Также: http://dotnetzip.codeplex.com/ - хорошая библиотека для создания zip-файлов, которые вы можете использовать для сжатия, написана на c #. Работал для меня довольно хорошо, и вы можете использовать встроенную функциональность создания множества файлов в одном zip-файле, чтобы разбить данные на куски.

...