Распаковка bzip2 в приложении для iOS

Я работаю над приложением для iOS, которое время от времени должно загружать ~50 МБ данных. bzip2 дает мне лучшую степень сжатия (уменьшает размер до 8 МБ).

Проблема в том, как распаковать данные в приложении?

Я провел некоторое исследование - единственные две вещи, которые я нашел, были Keka (но полный исходный код не является общедоступным) и исходный текст для C++ инструмента командной строки bzip2, который слишком длинный и слишком сложный для меня, чтобы внести необходимые корректировки для моего приложение в то время, которое я дал.

Я ищу что-то вроде http://commons.apache.org/proper/commons-compress/ которое используется в версии приложения для Android.

Если вы знаете, как сделать это с помощью 7zip вместо bzip2, это будет делать - это было немного менее эффективно.

3 ответа

Решение

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

Код, который вам нужно написать, будет выглядеть примерно так:

int error;
const int MAXSIZE = 4096;    // Or some other decent size.
char buffer[MAXSIZE];
FILE *f = fopen("somefile.bz2", "rb"); 
BZFILE* b = BZ2_bzReadOpen(&error, f, 0, 0, NULL, 0);
do {
   BZ2_bzRead(&error, b, buffer, MAXSIZE);
} while(error != BZ_OK);
BZ2_bzReadClose(&error, b);

Возможно, вам придется добавить еще несколько проверок на "ошибку", но концепция должна работать [я думаю - я только что набрал весь этот код, основываясь на документации и своем опыте использования этого и подобных пакетов в прошлом].

Я предлагаю вам статически ссылаться на libbz2. Найдите источники в Google.

Ответ Матса Петерссона указывает в правильном направлении, но он не полон.

Этот код работает на практике:

      #import "bzlib.h"

FILE * f = fopen (sourceURL.path.UTF8String, "rb");

int error;
const int MAXSIZE = 4096;
char processedBuffer [MAXSIZE];
char unprocessedBuffer [MAXSIZE];
int unprocessedCount = 0;

do
{
    BZFILE * b = BZ2_bzReadOpen (& error, f, 0, 0, unprocessedBuffer, unprocessedCount);
    while (error == BZ_OK)
    {
        int processedCount = BZ2_bzRead (& error, b, processedBuffer, MAXSIZE);
        
        // here you do what you need with uncompressed data
        for (int i = 0; i < processedCount; i ++)
            printf ("%c", processedBuffer [i]);
    }
    
    void * tmpBuf;
    BZ2_bzReadGetUnused (& error, b, & tmpBuf, & unprocessedCount);
    for (int i = 0; i < unprocessedCount; i ++)
        unprocessedBuffer [i] = ((char *) tmpBuf) [i];
    
    BZ2_bzReadClose (& error, b);
}
while (unprocessedCount > 0 || feof (f) == NO);

fclose (f);

Поскольку я включил bzip2 в качестве исходного кода, эти файлы необходимо добавить в проект:

      blocksort.c
bzlib_private.h
compress.c
crctable.c
decompress.c
huffman.c
randtable.c
bzlib.h
bzlib.c
Другие вопросы по тегам