Поиск:

Ответ в темуСоздание новой темы Создание опроса
> [QT4]qCompress() и qUncompress(), как реализовать упаковку/распаковку 
:(
    Опции темы
XavierElf
Дата 15.6.2008, 09:49 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 200
Регистрация: 24.1.2007
Где: г. Тверь

Репутация: нет
Всего: 1



Никак не могу понять как использовать эти функции для упаковки/распаковки файлов.
Делаю так:
Упаковка:
Код

    inFile.setFileName(argv[2]);
    inFile.open(QIODevice::ReadOnly);
    inArray = inFile.readAll();
    outFile.setFileName("archive.zip");
    outFile.open(QIODevice::WriteOnly);
    outStream.setDevice(&outFile);
    outStream << qCompress(inArray, 9);

Распаковка:
Код

    inFile.setFileName(argv[2]);
    inFile.open(QIODevice::ReadOnly);
    inArray = inFile.readAll();
    outFile.setFileName("proga.exe");
    outFile.open(QIODevice::WriteOnly);
    outStream.setDevice(&outFile);
    outStream << qUncompress(inArray);

Упаковывать - вроде упаковывает, а вот распаковывать не хочет... пишет:
Код

    qUncompress: Z_DATA_ERROR: Input data is corrupted

Кто посоветует, в какую сторону копать? smile 
--------------------
Даешь открытые исходники!
PM MAIL ICQ   Вверх
JackYF
Дата 15.6.2008, 11:43 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


полуавантюрист
****


Профиль
Группа: Участник
Сообщений: 5814
Регистрация: 28.8.2004
Где: страна тысячи озё р

Репутация: 7
Всего: 162



Цитата(XavierElf @  15.6.2008,  08:49 Найти цитируемый пост)
argv[2]

во втором случае точно содержит имя сжатого файла?


--------------------
Пожаловаться на меня как модератора можно здесь.
PM MAIL Jabber   Вверх
XavierElf
Дата 15.6.2008, 12:56 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 200
Регистрация: 24.1.2007
Где: г. Тверь

Репутация: нет
Всего: 1



Точно... Уж как только не бился - всё время выдаёт ошибку...  smile
--------------------
Даешь открытые исходники!
PM MAIL ICQ   Вверх
JackYF
Дата 15.6.2008, 19:15 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


полуавантюрист
****


Профиль
Группа: Участник
Сообщений: 5814
Регистрация: 28.8.2004
Где: страна тысячи озё р

Репутация: 7
Всего: 162



Так... А где у тебя код, привязывающий outStream к outFile?


--------------------
Пожаловаться на меня как модератора можно здесь.
PM MAIL Jabber   Вверх
XavierElf
Дата 15.6.2008, 20:26 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 200
Регистрация: 24.1.2007
Где: г. Тверь

Репутация: нет
Всего: 1



тут.
Код

outStream.setDevice(&outFile);

--------------------
Даешь открытые исходники!
PM MAIL ICQ   Вверх
SABROG
Дата 15.6.2008, 22:34 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Hacker
****


Профиль
Группа: Завсегдатай
Сообщений: 2481
Регистрация: 18.9.2006

Репутация: 81
Всего: 91



Файл находится в той же директории, что и программа ?
Вызови метод size() у QByteArray и сравни совпадает ли возвращаемое количество байт с количеством байт в файле.


--------------------
Национальная группа Russian Federation на QtCentre.
PM MAIL   Вверх
XavierElf
Дата 16.6.2008, 00:46 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 200
Регистрация: 24.1.2007
Где: г. Тверь

Репутация: нет
Всего: 1



Размеры идентичны... Уже не знаю в какую сторону копать smile У троллей описание по этим методам весьма скудное...
--------------------
Даешь открытые исходники!
PM MAIL ICQ   Вверх
BlackWolf1980
Дата 16.6.2008, 09:10 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 2
Регистрация: 16.6.2008

Репутация: нет
Всего: нет



сам возился, получалось так, что под виндой работало, под Ubuntu нет. решил так:
Запись:
Код

    QFile file ( "sqlcon.dat" );
    if ( !file.open ( QIODevice::WriteOnly | QIODevice::Text ) )
        return false;
    QByteArray strc = qCompress ( strd.toUtf8() );
    file.write ( strc );
    file.close()



Чтение:
    
Код

QFile file ( "sqlcon.dat" );
    if ( !file.open ( QIODevice::ReadOnly | QIODevice::Text ) )
        return;
    QByteArray infile;
    while ( !file.atEnd() )
    {
        infile += file.readLine();
    }
    QByteArray line = qUncompress ( infile );

PM MAIL ICQ Jabber   Вверх
andrew_121
Дата 16.6.2008, 09:17 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Кодофей
****


Профиль
Группа: Завсегдатай
Сообщений: 3448
Регистрация: 3.1.2008

Репутация: 11
Всего: 33



Цитата(XavierElf @  16.6.2008,  00:46 Найти цитируемый пост)
У троллей описание по этим методам весьма скудное...

Это не методы.


--------------------
Удалил аккаунт. Прощайте!
PM MAIL   Вверх
SABROG
Дата 16.6.2008, 11:02 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Hacker
****


Профиль
Группа: Завсегдатай
Сообщений: 2481
Регистрация: 18.9.2006

Репутация: 81
Всего: 91



Это глобальные функции, которые были помещены в модуль QByteArray. При сжатии данных формируется 4х байтовый заголовок, в котором содержится количество не сжатых байтов, т.е. то, что мы должны получить после распаковки.

Функция qUncompress проверяет этот заголовок. Какая архитектура у процессора ? Little-Endian, Big-Endian ?

На обычных тачках, которые x86 формат записи байтов - Little-Endian (задом наперед). Qt же записывает заголовок в формате Big-Endian (как видим так и пишем). Отсюда может возникнуть косяк с распаковкой данных на компьютерах с разными процессорами. Хотя судя по FAQ'у zlib'a он пашет на всех процах. С другой стороны Qt сам передает количество ожидаемых байт:

Код

    do {
        baunzip.resize(len);
        res = ::uncompress((uchar*)baunzip.data(), &len,
                            (uchar*)data+4, nbytes-4);

        switch (res) {
        case Z_OK:
            if ((int)len != baunzip.size())
                baunzip.resize(len);
            break;
        case Z_MEM_ERROR:
            qWarning("qUncompress: Z_MEM_ERROR: Not enough memory");
            break;
        case Z_BUF_ERROR:
            len *= 2;
            break;
        case Z_DATA_ERROR:
            qWarning("qUncompress: Z_DATA_ERROR: Input data is corrupted");
            break;
        }
    } while (res == Z_BUF_ERROR);


Если копать дальше, то Z_DATA_ERROR возникает тут:

Код

int Q_ZEXPORT uncompress (dest, destLen, source, sourceLen)
    Bytef *dest;
    uLongf *destLen;
    const Bytef *source;
    uLong sourceLen;
{
    z_stream stream;
    int err;

    stream.next_in = (Bytef*)source;
    stream.avail_in = (uInt)sourceLen;
    /* Check for source > 64K on 16-bit machine: */
    if ((uLong)stream.avail_in != sourceLen) return Z_BUF_ERROR;

    stream.next_out = dest;
    stream.avail_out = (uInt)*destLen;
    if ((uLong)stream.avail_out != *destLen) return Z_BUF_ERROR;

    stream.zalloc = (alloc_func)0;
    stream.zfree = (free_func)0;

    err = inflateInit(&stream);
    if (err != Z_OK) return err;

    err = inflate(&stream, Z_FINISH);
    if (err != Z_STREAM_END) {
        inflateEnd(&stream);
        if (err == Z_NEED_DICT || (err == Z_BUF_ERROR && stream.avail_in == 0))
            return Z_DATA_ERROR;
        return err;
    }
    *destLen = stream.total_out;

    err = inflateEnd(&stream);
    return err;
}


Это сообщение отредактировал(а) SABROG - 16.6.2008, 11:29


--------------------
Национальная группа Russian Federation на QtCentre.
PM MAIL   Вверх
XavierElf
Дата 16.6.2008, 14:02 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 200
Регистрация: 24.1.2007
Где: г. Тверь

Репутация: нет
Всего: 1



Насчёт методов - я оговорился. А вот по поводу моей проблемы конкретного решения я так и не услышал. У меня стоит Kubuntu 8.04 x86_64 и Windows XP x32. Ни там, ни там не получается сжать, а потом распаковать файл. Если можно, хотелось бы глянуть, как это правильно реализовать. Кто-нибудь может показать полностью рабочий код, который позволяет сжать файл, а потом распаковать его?
--------------------
Даешь открытые исходники!
PM MAIL ICQ   Вверх
BlackWolf1980
Дата 16.6.2008, 15:50 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 2
Регистрация: 16.6.2008

Репутация: нет
Всего: нет



Цитата(XavierElf @ 16.6.2008,  14:02)
Насчёт методов - я оговорился. А вот по поводу моей проблемы конкретного решения я так и не услышал. У меня стоит Kubuntu 8.04 x86_64 и Windows XP x32. Ни там, ни там не получается сжать, а потом распаковать файл. Если можно, хотелось бы глянуть, как это правильно реализовать. Кто-нибудь может показать полностью рабочий код, который позволяет сжать файл, а потом распаковать его?

смотри выше, я тебе привел реальный код, могу весь класс скинуть.
проверял как под Ubuntu 8.04 так и под Win XP
PM MAIL ICQ Jabber   Вверх
SABROG
Дата 16.6.2008, 16:54 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Hacker
****


Профиль
Группа: Завсегдатай
Сообщений: 2481
Регистрация: 18.9.2006

Репутация: 81
Всего: 91



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

user posted image

Присоединённый файл ( Кол-во скачиваний: 79 )
Присоединённый файл  CompressDecompress.zip 1,91 Kb


--------------------
Национальная группа Russian Federation на QtCentre.
PM MAIL   Вверх
XavierElf
Дата 16.6.2008, 17:30 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 200
Регистрация: 24.1.2007
Где: г. Тверь

Репутация: нет
Всего: 1



2 BlackWolf1980, спасибо, но мне нужно сжимать бинарные файлы в основном...
2 SABROG, ваш пример выдает тоже самое... что под виндой, что под линуксом...
Код

qUncompress: Z_DATA_ERROR: Input data is corrupted

не пойму, что не так... smile
--------------------
Даешь открытые исходники!
PM MAIL ICQ   Вверх
SABROG
Дата 16.6.2008, 17:34 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Hacker
****


Профиль
Группа: Завсегдатай
Сообщений: 2481
Регистрация: 18.9.2006

Репутация: 81
Всего: 91



Может дело в файле ? Больше 4294967295 байт (4 гигов) не сжать.

Кстати, не знаю почему, но файл размером всего в 60 мегабайт сжимался около минуты. Хотя и винрар был не особо быстр - 40 секунд.

Это сообщение отредактировал(а) SABROG - 16.6.2008, 17:41


--------------------
Национальная группа Russian Federation на QtCentre.
PM MAIL   Вверх
Ответ в темуСоздание новой темы Создание опроса
Правила форума "С/С++: Кроссплатформенное программирование, QT/Gtk+/wxWidgets"
JackYF
Любитель
  • В заголовке темы в квадратных скобках обозначьте используемую вами библиотеку, например: [QT],[GTK],[wx].
  • Если вопрос актуален только для некоторой версии библиотеки, либо, если вы пользуетесь не самой последней версией, укажите это. Например: [QT4], [GTK2].
  • Все начинающие изучать Qt - не забудьте зайти сюда.
  • Проставьте несколько ключевых слов темы, чтобы её можно было легче найти.
  • В вопросе укажите полную версию версию библиотеки, а также все дополнительные используемые программные пакеты.
  • Не забывайте пользоваться кнопкой "Код".
  • Телепатов на форуме нет! Задавайте чёткий, конкретный и полный вопрос. Указывайте полностью ошибки компилятора и компоновщика.
  • Новое сообщение должно иметь прямое отношение к тематике этого раздела. Флуд, флейм, оффтопик запрещены.
  • Категорически запрещается обсуждение вареза, "кряков", взлома программ и т.д.

Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, JackYF, Любитель.

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | С/С++: Кроссплатформенное программирование, Qt/Gtk+/wxWidgets | Следующая тема »


 




[ Время генерации скрипта: 0.0563 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.