crossplatform.ru

Здравствуйте, гость ( Вход | Регистрация )


  Ответ в ZIP архив создать программно как ?
Введите ваше имя
Подтвердите код

Введите в поле код из 6 символов, отображенных в виде изображения. Если вы не можете прочитать код с изображения, нажмите на изображение для генерации нового кода.
Теги
Выровнять по центру
Ссылка на тему
Ссылка на сообщение
Скрытый текст
Сокращение
Код с подсветкой
Offtopic
 
Удалить форматирование
Спец. элементы
Шрифт
Размер
 
Цвет шрифта
 
Отменить ввод
Вернуть ввод
Полужирный
Курсив
Подчеркнутый
 
 
Смайлики
Вставить изображение
Вставить адрес электронной почты
Цитата
Код
Раскрывающийся текст
 
Увеличить отступ
По левому краю
По центру
По правому краю
Вставить список
Вставить список

Опции сообщения
 Включить смайлы?
Иконки сообщения
(Опционально)
                                
                                
  [ Без иконки ]
 


Последние 10 сообщений [ в обратном порядке ]
SABROG Дата 12.10.2009, 15:19
  Плохо это решение тем, что оно не переносимо, ибо этот Wizard dll API зависим в то время как внутренние вызовы самой библиотеки InfoZip переносимы. Т.е., чтобы понять как это работает и правильно написать код, надо сначала переписать Wizard dll на обычном C++ с использованием STL или обычном Си. Потом уже этот код использовать в Qt.
filinGUI Дата 12.10.2009, 15:11
 
Цитата(SABROG @ 12.10.2009, 15:30) *
Найти бы еще пример как это делать. Мои копания примеров этой утилиты привели только к одному заключению - функций типа createZip()/Unzip() нет. Т.е. нужно делать какие-то подготовительные телодвижения, логика которых не становится понятной глядя на код.


Таких простых функций действительно нет, для упаковки используется последовательность вызовов ZpInit / ZpSetOptions / ZpArchive, для распаковки вызывается Wiz_SingleEntryUnzip. Для своего проекта я написал функцию SimpleUnzip (Qt3, библиотека Unzip.dll загружается динамически)
Раскрывающийся текст
//---------------------------------------------------------------------------
//  Служебные функции для SimpleUnzip
//---------------------------------------------------------------------------
int WINAPI DummyPrint(LPSTR, unsigned long) {return 0;}
int WINAPI DummyReplace(LPSTR) {return 0;}
int WINAPI DummyPassword(LPSTR, int, LPCSTR, LPCSTR) {return 0;}
void WINAPI DummyMessage(unsigned long, unsigned long, unsigned,
    unsigned, unsigned, unsigned, unsigned, unsigned,
    char, LPSTR, LPSTR, unsigned long, char) {}

//---------------------------------------------------------------------------
//  Распаковывает zip-архив a_zip в каталог a_dir, заменяя существующие файлы
//---------------------------------------------------------------------------
typedef int (WINAPI * FSINGLEENTRYUNZIP)( int, char **, int, char **,
                                          LPDCL, LPUSERFUNCTIONS );
bool SimpleUnzip( const QString& a_zip, const QString& a_dir )
{
    const QString noZip = ru( "Обработка архивов zip невозможна." );
    const QString errCap = ru("Ошибка");
    const TCHAR* UNZ_DLL_NAME = TEXT("unzip32.dll");
    TCHAR szFullPath[_MAX_PATH];
    TCHAR* ptr;
    if ( SearchPathW( 0, UNZ_DLL_NAME, 0,
                      sizeof(szFullPath) / sizeof(szFullPath[ 0 ]),
                      szFullPath, &ptr ) == 0 )
    {
        mbE( errCap, ru("Не найдена библиотека unzip32.dll.\n" + noZip ) );
        return false;
    }

    HMODULE hUnzipDll = LoadLibraryW( UNZ_DLL_NAME );
    if ( hUnzipDll == 0 )
    {
        mbE( errCap, ru("Не удалось загрузить библиотеку unzip32.dll.\n" + noZip ) );
        return false;
    }

    FSINGLEENTRYUNZIP pWiz_SingleEntryUnzip = (FSINGLEENTRYUNZIP)GetProcAddress(
        hUnzipDll, "Wiz_SingleEntryUnzip" );
    if ( pWiz_SingleEntryUnzip == 0 )
    {
        FreeLibrary( hUnzipDll );
        mbE( errCap, ru("Неправильная библиотека unzip32.dll.\n" + noZip ) );
        return false;
    }

    LPDCL lpDCL = new DCL;
    LPUSERFUNCTIONS lpUserFunctions = new USERFUNCTIONS;

    lpUserFunctions->password = DummyPassword;
    lpUserFunctions->print = DummyPrint;
    lpUserFunctions->replace = DummyReplace;
    lpUserFunctions->SendApplicationMessage = DummyMessage;
    lpUserFunctions->sound = 0;
    lpUserFunctions->ServCallBk = 0;

    //set up the flags to be passed into the dll.
    lpDCL->ExtractOnlyNewer = 0;  // Do not extract only newer
    lpDCL->SpaceToUnderscore = 0;
    lpDCL->PromptToOverwrite = 0; // "Overwrite all" selected, no query mode
    lpDCL->fQuiet = 2; // 0 = all messages, 1 = fewer messages, 2 = no messages
    lpDCL->ncflag = 0; // Write to stdout if true
    lpDCL->ntflag = 0; // Do not test zip file
    lpDCL->nvflag = 0; // Do not give a verbose listing
    lpDCL->nfflag = 0; // Do not freshen existing files only
    lpDCL->nzflag = 0; // display a zip file comment if true
    lpDCL->ndflag = 1; // Recreate directories != 0, skip "../" if < 2
    lpDCL->noflag = 1; // Over-write all files
    lpDCL->naflag = 0; // Do not convert CR to CRLF
    lpDCL->nZIflag = 0;// Do not get ZipInfo
    lpDCL->C_flag = 1; // Do not be case insensitive
    lpDCL->fPrivilege = 0;  // 1 => restore ACLs in user mode,
                        // 2 => try to use privileges for restoring ACLs

    QCString zip = a_zip.local8Bit();
    QCString dir = a_dir.local8Bit();
    lpDCL->lpszZipFN = const_cast<CHAR*>(static_cast<const char*>(zip));
    if ( a_dir.isEmpty() )
        lpDCL->lpszExtractDir = 0;
    else
        lpDCL->lpszExtractDir = const_cast<CHAR*>(static_cast<const char*>(dir));

//    qDebug( "zip=%s, dir=%s", lpDCL->lpszZipFN, lpDCL->lpszExtractDir );
    int res = pWiz_SingleEntryUnzip( 0, 0, 0, 0, lpDCL, lpUserFunctions );
//    qDebug( "unzip retcode=%d", res );
    bool rc = res == 0;

    delete lpDCL;
    delete lpUserFunctions;
    FreeLibrary( hUnzipDll );

    return rc;
}


Могу дать ещё пример SimpleZip для упаковки, но только на Delphi
SABROG Дата 12.10.2009, 14:30
 
Цитата(filinGUI @ 12.10.2009, 15:11) *
flankerr

Архивирование с вложенными каталогами и отображением прогресса можно сделать, используя Info-ZIP. Архив получается вполне стандартный и распакуется везде. Надо только собрать zip и unzip как dll и написать callback-функцию для отображения прогресса.


Найти бы еще пример как это делать. Мои копания примеров этой утилиты привели только к одному заключению - функций типа createZip()/Unzip() нет. Т.е. нужно делать какие-то подготовительные телодвижения, логика которых не становится понятной глядя на код.
filinGUI Дата 12.10.2009, 14:11
  flankerr

Архивирование с вложенными каталогами и отображением прогресса можно сделать, используя Info-ZIP. Архив получается вполне стандартный и распакуется везде. Надо только собрать zip и unzip как dll и написать callback-функцию для отображения прогресса.
kwisp Дата 12.10.2009, 8:23
  kuzulis,
первый пост об этом говорит.
kuzulis Дата 12.10.2009, 8:13
  А почему автору нельзя использовать сторонние архиваторы?

Проще, ИМХО, через QProcess их вызывать и в опциях командной строки подсовывать нужные каталоги для сжатия...

Для этого в самой программе автора определять - какие из архиваторов находятся в системе... НЕ ? :)
BRE Дата 11.10.2009, 12:46
 
Цитата(Litkevich Yuriy @ 11.10.2009, 13:33) *
в KDE в большенстве случаев индикатор выполнения болтается туда-сюда.

Если писать свой враппер, то это можно сделать как надо:
* Открыть архив
* Найти по имени файла его индекс
* Получить информацию о файле по индексу (необходим размер распакованных данных)
* В цикле читаем данные файла из архива кусками и посылаем сигнал о прогрессе.
Litkevich Yuriy Дата 11.10.2009, 12:33
  в KDE в большенстве случаев индикатор выполнения болтается туда-сюда.
BRE Дата 11.10.2009, 12:25
  Можно посмотреть решение в KDE. Там правда все сделано глобально, т.е. есть целая иерархия классов начиная с KArchive. У него есть наследник KZip.
Или посмотреть на библиотеку libzip. Она сишная, но можно самому написать враппер для C++ со всем необходимым функционалом.
Также вроде есть готовый враппер libzipios++.
SABROG Дата 9.10.2009, 23:39
 
Цитата(Litkevich Yuriy @ 9.10.2009, 19:28) *
Однако исодники у них открыты, или я ошибаюсь?

Открыты, только тогда придеться брать исходники p7zip (порт под linux). Там вроде бы какраз есть директория zip с исходниками. Думаю там точно такая же канитель будет с пониманием ABI, как и в InfoZip.
Просмотр темы полностью (откроется в новом окне)
RSS Рейтинг@Mail.ru Текстовая версия Сейчас: 10.7.2025, 17:21