Модераторы: feodorv
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Выборочное скачивание файлов из ZIP–архива, Как можно такое реализовать? 
V
    Опции темы
MuForum
Дата 15.5.2011, 16:21 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 427
Регистрация: 13.6.2007
Где: Молдова, Кишинев

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



Доброго времени суток.

# Задача: Реализовать выборочное скачивание файлов из ZIP–архива;


# Дополнение:
Цитата

1. Данный функционал реализован в программе ReGet Deluxe 4.0;

2. Сайт посвещённый формату Zip: Перейти;

3. ZIP File Format Specification: Перейти;

4. ZIP (file format): Wiki;

5. Работаем с ZIP-файлами: Структура ZIP-файла;



P.S. ->  Можете подсказать какие-то статьи, ресурсы и т.д. по данному вопросу?

Это сообщение отредактировал(а) MuForum - 15.5.2011, 20:46


--------------------
"Чтобы правильно задать вопрос, нужно знать большую часть ответа!" (Р. Шекли)
PM MAIL WWW ICQ Skype MSN   Вверх
boostcoder
Дата 15.5.2011, 17:32 (ссылка) |    (голосов:1) Загрузка ... Загрузка ... Быстрая цитата Цитата


pattern`щик
****


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

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



сначала читаешь заголовок ZIP-архива.
из заголовка узнаешь имена файлов и их смещение в архиве.
скачиваешь диапазон байтов.
применяешь к скачанному алгоритм распаковки.

единственное что тут нужно читать, так это структуру ZIP-архива.

PM WWW   Вверх
MuForum
Дата 15.5.2011, 20:01 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 427
Регистрация: 13.6.2007
Где: Молдова, Кишинев

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



Вот сделал структуры, который нашел в описании...
Код


typedef struct // 30 bytes;
{
    UINT    LocalFileHeaderSignature; // = 0x04034b50;
    USHORT    VersionNeededToExtract;
    USHORT    GeneralPurposeBitFlag;
    USHORT    CompressionMethod;
    USHORT    LastModFileTime;
    USHORT    LastModFileDate;
    UINT    CRC32;
    UINT    CompressedSize;
    UINT    UncompressedSize;
    USHORT    FileNameLength;
    USHORT    ExtraFieldLength;
} LocalFileHeader, *PLocalFileHeader;

typedef struct // 16 bytes;
{
    UINT    LocalFileHeaderSignature; // = 0x08074b50;
    UINT    CRC32;
    UINT    CompressedSize;
    UINT    UncompressedSize;
} DataDescriptor, *PDataDescriptor;

typedef struct // 46 bytes;
{
    UINT    CentralDirectoryFileHeaderSignature; // = 0x02014b50;
    USHORT    VersionMadeBy;
    USHORT    VersionNeededToExtract; // Minimum;
    USHORT    GeneralPurposeBitFlag;
    USHORT    CompressionMethod;
    USHORT    FileLastModificationTime;
    USHORT    FileLastModificationDate;
    UINT    CRC32;
    UINT    CompressedSize;
    UINT    UncompressedSize;
    USHORT    FileNameLength;
    USHORT    ExtraFieldLength;
    USHORT    FileCommentLength;
    USHORT    DiskNumberWhereFileStarts;
    USHORT    InternalFileAttributes;
    UINT    ExternalFileAttributes;
    UINT    RelativeOffsetOfLocalFileHeader;
} CentralDirectoryFileHeader, *PCentralDirectoryFileHeader;

typedef struct // 22 bytes;
{
    UINT    EndOfCentralDirectorySignature; // = 0x06054b50;
    USHORT    NumberOfThisDisk;
    USHORT    DiskWhereCentralDirectoryStarts;
    USHORT    NumberOfCentralDirectoryRecordsOnThisDisk;
    USHORT    TotalNumberOfCentralDirectoryRecords;
    UINT    SizeOfCentralDirectory;
    UINT    OffsetOfStartOfCentralDirectory;
    USHORT    FileCommentLength;
} EndOfCentralDirectoryRecord, *PEndOfCentralDirectoryRecord;


P.S. -> Может кто-то подскажет ещё что-то или какой-то косяк если есть.

# Добавлено:
Если я правильно понял, то схема следующая:
1. Сначала идут "ZIP local file header", причём эта структура и для файлов и для папок.
- Если папка, то создаётся 1 структура "ZIP local file header", после чего идёт "ZIP local file header" для файла и дальше не могу понять что.

Это сообщение отредактировал(а) MuForum - 15.5.2011, 20:37


--------------------
"Чтобы правильно задать вопрос, нужно знать большую часть ответа!" (Р. Шекли)
PM MAIL WWW ICQ Skype MSN   Вверх
500mhz
Дата 15.5.2011, 23:03 (ссылка)    | (голосов:2) Загрузка ... Загрузка ... Быстрая цитата Цитата


шайтан
***


Профиль
Группа: Завсегдатай
Сообщений: 1017
Регистрация: 5.5.2008
Где: Киев / Italy

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



а если solid то хрен что получится


--------------------

PM MAIL ICQ   Вверх
borisbn
Дата 16.5.2011, 01:47 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


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

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



IMHO проще будет потренероваться на локальном zip-файле, а затем заменить ф-ции seek и read на соответствующие сетевые запросы...


--------------------
Женщины отличаются от программистов тем, что у них чары состоят из стрингов
PM MAIL Jabber   Вверх
MuForum
Дата 16.5.2011, 02:05 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 427
Регистрация: 13.6.2007
Где: Молдова, Кишинев

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



Цитата(borisbn @ 16.5.2011,  01:47)
IMHO проще будет потренероваться на локальном zip-файле, а затем заменить ф-ции seek и read на соответствующие сетевые запросы...

Так и сделал.
Уже разобрался с размещением данных в архиве, всё оказалось очень просто...
Теперь вот ломаю голову над обратной операцией сжатия алгоритмом Deflate.
- Использовать какие-то .dll не могу, так как мне нужны исходники, так как это дело необходимо заточить под многопоточноть =(

# Добавлено:
Цитата

Features of 7za.dll: 
  - Supporting 7z format;
  - Built encoders: LZMA, PPMD, BCJ, BCJ2, COPY, AES-256 Encryption.
  - Built decoders: LZMA, PPMD, BCJ, BCJ2, COPY, AES-256 Encryption, BZip2, Deflate.

Интересно, а 7za.dll поддерживает многопоточность?

Это сообщение отредактировал(а) MuForum - 16.5.2011, 02:41


--------------------
"Чтобы правильно задать вопрос, нужно знать большую часть ответа!" (Р. Шекли)
PM MAIL WWW ICQ Skype MSN   Вверх
MuForum
Дата 16.5.2011, 12:13 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 427
Регистрация: 13.6.2007
Где: Молдова, Кишинев

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



# Вопрос: У кого-то есть исходники декодирования алгоритма Deflate на C/C++ под ПК?

Я разобрал структуру .zip архива.
Она очень простая, ничего сложного нет как пишат сказки...
Всё очень протсо...
Читаешь размер файла, с конца считываешь 22 байта(структура конца центральной секции), там находится адрес начала центральной секции, и сначала файла начинаешь находить нужный тебе файл по заголовкам 30 байт + длина имени файла + длина доп.инфы.
Мне теперь нужно как-то расспаковывать данные.
Использовать левые библиотеки не могу, так как у меня задача это реализовать под многоядерность...
А все реализации сделаны в виде .dll, которые заточены строго под одно ядро да ещё и почти всё static....


# Добавлено:
1. Заходим на сайт http://zlib.net/ и скачиваем последние исходники.
- zlib source code, version 1.2.5;
2. Распаковываем архив: zlib-1.2.5\contrib\puff
- Лежат два файла: puff.c/puff.h
- int puff(BYTE * dest,  ULONG * destlen,  BYTE * source, ULONG * sourcelen);


P.S. -> Кому надо в общем уже может переделать под себя.
- Спасибо "borisbn" за подсказку.

Это сообщение отредактировал(а) MuForum - 16.5.2011, 15:23


--------------------
"Чтобы правильно задать вопрос, нужно знать большую часть ответа!" (Р. Шекли)
PM MAIL WWW ICQ Skype MSN   Вверх
boostcoder
Дата 16.5.2011, 16:27 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


pattern`щик
****


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

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



так в zlib`е есть deflate.
или что?
PM WWW   Вверх
MuForum
Дата 16.5.2011, 17:13 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 427
Регистрация: 13.6.2007
Где: Молдова, Кишинев

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



# Внимание! В исходниках zlib версии 1.2.5 в файле puff.c обнаружился баг при котором программа которая использует данные исходники падает.
Код

local int fixed(struct state *s)
{
    static int virgin = 1;
    static short lencnt[MAXBITS+1], lensym[FIXLCODES];
    static short distcnt[MAXBITS+1], distsym[MAXDCODES];
    static struct huffman lencode, distcode;

    /* build fixed huffman tables if first call (may not be thread safe) */
    if (virgin) {
        int symbol;
        short lengths[FIXLCODES];

        /* literal/length table */
        for (symbol = 0; symbol < 144; symbol++)
            lengths[symbol] = 8;
        for (; symbol < 256; symbol++)
            lengths[symbol] = 9;
        for (; symbol < 280; symbol++)
            lengths[symbol] = 7;

        for (; symbol < FIXLCODES; symbol++)
            lengths[symbol] = 8;
        construct(&lencode, lengths, FIXLCODES);

        /* distance table */
        for (symbol = 0; symbol < MAXDCODES; symbol++)
            lengths[symbol] = 5;
        construct(&distcode, lengths, MAXDCODES);

        /* construct lencode and distcode */
        lencode.count = lencnt;
        lencode.symbol = lensym;
        distcode.count = distcnt;
        distcode.symbol = distsym;

        /* do this just once */
        virgin = 0;
    }

    /* decode data until end-of-block code */
    return codes(s, &lencode, &distcode);
}

- Данная функция вызывается лишь в том случае, если при сжатие файлов в архиве используется уровень сжатия "Максимальный/Ультра".
- Правиться это легко и просто, задав заранее указатели на доп.массивы.
Код

local int fixed(struct state *s)
{
    static int virgin = 1;
    static short lencnt[MAXBITS+1], lensym[FIXLCODES];
    static short distcnt[MAXBITS+1], distsym[MAXDCODES];
    static struct huffman lencode, distcode;

    /* build fixed huffman tables if first call (may not be thread safe) */
    if (virgin) {
        int symbol;
        short lengths[FIXLCODES];

        /* literal/length table */
        for (symbol = 0; symbol < 144; symbol++)
            lengths[symbol] = 8;
        for (; symbol < 256; symbol++)
            lengths[symbol] = 9;
        for (; symbol < 280; symbol++)
            lengths[symbol] = 7;

        lencode.count = lencnt;
        lencode.symbol = lensym;

        for (; symbol < FIXLCODES; symbol++)
            lengths[symbol] = 8;
        construct(&lencode, lengths, FIXLCODES);

       distcode.count = distcnt;
        distcode.symbol = distsym;

        /* distance table */
        for (symbol = 0; symbol < MAXDCODES; symbol++)
            lengths[symbol] = 5;
        construct(&distcode, lengths, MAXDCODES);

        /* do this just once */
        virgin = 0;
    }

    /* decode data until end-of-block code */
    return codes(s, &lencode, &distcode);
}



P.S. -> В большей степени можно сказать что это не баг, а просто невнимательность разработчиков.
- Но им огромный респект за этот труд. Благодаря zlib моя проблема решилась как два пальца...

# Добавлено:
- Так же прикрепляю архив сжатый в режиме "Ультра/Максимум", при попытки которого происходит exception.
- Падение на файле "eDS_Leo123/TTest.h";

Это сообщение отредактировал(а) MuForum - 16.5.2011, 17:18

Присоединённый файл ( Кол-во скачиваний: 3 )
Присоединённый файл  Documents.zip 14,96 Kb


--------------------
"Чтобы правильно задать вопрос, нужно знать большую часть ответа!" (Р. Шекли)
PM MAIL WWW ICQ Skype MSN   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | C/C++: Сети | Следующая тема »


 




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


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

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