Форум программистов, компьютерный форум, киберфорум
С++ для начинающих
Войти
Регистрация
Восстановить пароль
Карта форума Темы раздела Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.72/88: Рейтинг темы: голосов - 88, средняя оценка - 4.72
56 / 50 / 22
Регистрация: 17.03.2014
Сообщений: 142
1

Распаковка zip-архива средствами С++

23.09.2015, 04:37. Показов 16995. Ответов 10
Метки нет (Все метки)

Author24 — интернет-сервис помощи студентам
Помогите считать из zip-архива файлы в кодировке Unicode (UTF-8).
Долго копался в ресурсах на эту тему, но так и не нашел решения. Среди рассмотренных вариантов были:
- библиотека zlib (она умеет непосредственно сжимать/разжимать файлы, но, как и я, не понимает структуру архива)
- библиотека unzipper (помещает содержимое сжатого файла в строковую переменную строго в формате ANSI, и потому не подходит)
- еще несколько библиотек, которые при подключении соответствующих файлов выдавали ошибки и не работали
Буду очень благодарен за доступное объяснение и/или ссылку на инфу о чтении заголовочного файла архива, или библиотеку, позволяющую извлекать файлы из zip с поддержкой юникода.
1
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
23.09.2015, 04:37
Ответы с готовыми решениями:

Распаковка архива
Как распаковать rar и zip архивы? p.s. сейчас я это делаю через запуск стороннего софта через...

Zip запаковка\распаковка данных со смещением
Воспользовавшись программой Offset file unzipper 0.3.6a узнал что у файла смещение(hex offset) = 3,...

Создание ZIP архива
Есть несколько xml файлов. Надо их засунуть в 1 архив. Есть-ли подходящая либа на плюсах? Про zlib...

Создание архива rar/zip на C++
Народ, такая ситуация, мне необходимо создать архив rar или zip (желательно rar, запароленный) при...

10
3176 / 1935 / 312
Регистрация: 27.08.2010
Сообщений: 5,131
Записей в блоге: 1
23.09.2015, 13:12 2
Содержимое файла никак не связано с его архивированием (влияет только на степень сжатия). Кодировка - это забота вьювера, неважно, будь там Unicode или MP3.

Разделите эти две задачи - упаковку и просмотр, и будет вам щастье.
0
56 / 50 / 22
Регистрация: 17.03.2014
Сообщений: 142
23.09.2015, 17:08  [ТС] 3
gazlan, очевидные вещи говорите. Вопрос о чтении кодировки как таковой не стоит, однако, у меня проблемы с распаковкой. Единственная библиотека с которой я подружился, выгружает содержимое архивных файлов в текстовые переменные (причем без чтения юникода), что как раз является частным случаем, когда обе проблемы совмещены в одну. Пока что работа с архивами остается вне зоны моего понимания.
0
3176 / 1935 / 312
Регистрация: 27.08.2010
Сообщений: 5,131
Записей в блоге: 1
23.09.2015, 21:22 4
Цитата Сообщение от kaznachei67 Посмотреть сообщение
выгружает содержимое архивных файлов в текстовые переменные
Где вам удалось найти такое?

На сайте ZLib есть примеры, вы можете распаковать ZIP-stream в memory buffer (или что-либо другое, по вкусу) и дальше обрабатывать этот буфер как заблагорассудится.

Не по теме:

(Ex: мой Ebook Unpacker дешифрует и распаковывает encrypted ZIP-streams и воссоздает на диске весь упакованный сайт - включая HTML, GIF, PNG, JPG, DOC ... other ZIP's ... все что было запихнуто туда автором - не спрашивая ни про формат, ни про кодировку).

0
56 / 50 / 22
Регистрация: 17.03.2014
Сообщений: 142
23.09.2015, 22:43  [ТС] 5
Я много чего уже успел пересмотреть.
Касательно Zlib: насколько я понимаю, описанные в примере функции реализуют компрессию/декомпрессию файлов, но сам формат .zip библиотека не обрабатывает. Предположительно, нужно как-то разобрать заголовок архива и скормить полученную информацию deflate(). Вот только как это сделать?

Не по теме:

По вашей ссылке ругается на битый архив

0
7792 / 6559 / 2984
Регистрация: 14.04.2014
Сообщений: 28,668
23.09.2015, 23:16 6
Вот здесь про формат zip-файлов: http://www.winimage.com/zLibDll/minizip.html
(See appnote-011203-iz.zip or appnote-iz-latest.zip for the specification of ZIP format...)
Он какой-то путаный, там по-видимому его расширяли от древних версий.
Основа читается просто, сами сжатые данные - это "file data". Не понятно, как интерпретировать имена файлов, по умолчанию 866-я кодировка. Встроенный zip в Windows отказывается создавать архив с файлами, у которых в именах, например, иероглифы. WinRar создаёт, но там не понятно какая кодировка используется.
0
3176 / 1935 / 312
Регистрация: 27.08.2010
Сообщений: 5,131
Записей в блоге: 1
23.09.2015, 23:29 7
Заголовок ZIP (если он есть и стандартный) описан в RFC и еще во многих местах (начиная с wiki).
RFC-1951 - DEFLATE Compressed Data Format Specification version 1.3
RFC 1952 - GZIP file format specification version 4.3

deflate бесполезен для распаковки, вам нужен inflate.

Сделать это просто: inflateInit2() инициализирует ZIP-object, inflate() распаковывает поток. Необходимые данные берутся из заголовка, размер окна лучше указывать максимальный:
C++
1
2
3
int   iErr = inflateInit2(&zipstream,-MAX_WBITS);
...
iErr = inflate(&zipstream,Z_NO_FLUSH);
Всю процедуру вы можете рассматривать как работу с двумя ящиками: с ZipBox и с OutBox.

inflate() забирает данные из буфера ZipBox, распаковывает их и перекладывает в буфер OutBox.

Полагая, что сам ZIP-stream OK, у вас возможны всего две ошибки:
  • Кончились входные данные - сбрасываете на диск (или куда требуется) OutBox и завершаете работу с потоком.
  • Кончилось свободное пространство в OutBox - сбрасываете на диск (или куда требуется) OutBox, очищаете буфер и продолжаете работу с потоком.

Все это, с хорошо комментированным примером, есть по приведенной ранее ссылке.

Цитата Сообщение от kaznachei67 Посмотреть сообщение
ругается на битый архив
Обновите ваш WinRar до версии 5+
test
RAR 5.30 beta 2 Copyright (c) 1993-2015 Alexander Roshal 18 Aug 2015

Testing archive ebu.rar

Testing ebu\ebu.com  87% OK
Testing ebu\ebu.txt  89% OK
Testing ebu OK
Testing the recovery record  0% 33% 66% OK
All OK

Ниже простейший (без цикла выгрузки OutBox) пример распаковки eBooks, созданных в WebExe.
  • На первом шаге MMF сканируется на наличие ZIP-архивов, найденные адреса сохраняются в массиве.
  • На втором шаге все найденные потоки распаковываются "в один глоток" и сохраняются на диск.
Simplest sample

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
   // Open eBook File
   MMF      eBook;
 
   if (!eBook.OpenReadOnly(argv[1]))
   {
      // Error !
      printf("Can't open file [%s]\n",argv[1]);
      return -1;
   }
 
   // Do Actual Work
   const DWORD    dwPKZipSigz = 0x04034B50;
 
   bool     bFound = false;
 
   QuickSearch((BYTE*)&dwPKZipSigz,sizeof(DWORD),eBook.Buffer(),eBook.Size() - sizeof(dwPKZipSigz),&bFound,Finder);
 
   // Append false last entry
   dwOfsArr[iCnt++] = eBook.Size();
 
   char     pszZip      [_MAX_PATH];
   char     pszDrive    [_MAX_DRIVE];
   char     pszDir      [_MAX_DIR];
   char     pszFName    [_MAX_FNAME];
   char     pszExt      [_MAX_EXT];
 
   _splitpath(argv[1],pszDrive,pszDir,pszFName,pszExt);
 
   printf("Total records: %d\n\n",iCnt - 1);
 
   for (int ii = 0; ii < (iCnt - 1); ++ii)
   {
      // Get Header
      ZIP_LOCAL_FILE_HEADER*     pLFHeader = (ZIP_LOCAL_FILE_HEADER*)(eBook.Buffer() + dwOfsArr[ii]);
 
      BYTE     pOut[USHRT_MAX];  // I hope, it is enough !
 
      memset(pOut,0,sizeof(pOut));
      
      char     pszTemp[MAX_PATH];
 
      wsprintf(pszTemp,"%s_%03d",pszFName,ii + 1);
      _makepath(pszZip,pszDrive,pszDir,pszTemp,"HTM");
 
      HANDLE      hFile = CreateFile(pszZip);
 
      if (hFile == INVALID_HANDLE_VALUE)
      {
         // Error !
         printf("Can't create file [%s]\n",pszZip);
         continue;
      }
 
      z_stream    ZipStream;
 
      memset(&ZipStream,0,sizeof(ZipStream));
 
      int   iErr = 0;
      
      iErr = inflateInit2(&ZipStream,-MAX_WBITS);
 
      if (iErr != Z_OK)
      {
         printf("INFLATEINIT2 Err %d,%s\n",ZipStream.msg);
      }
 
      BYTE*    pSrc = eBook.Buffer() +  + dwOfsArr[ii] + sizeof(ZIP_LOCAL_FILE_HEADER) + pLFHeader->_wFilenameLen + pLFHeader->_wExtraLen;
 
      ZipStream.next_in  = pSrc;
      ZipStream.avail_in = pLFHeader->_dwPackSize;
 
      ZipStream.next_out  = pOut;
      ZipStream.avail_out = USHRT_MAX;
 
      iErr = inflate(&ZipStream,Z_SYNC_FLUSH);
 
      if ((iErr != Z_OK) && (iErr != Z_STREAM_END))
      {
         printf("INFLATE Err %d,%s\n",iErr,ZipStream.msg);
      }
 
      WriteBuffer(hFile,pOut,pLFHeader->_dwOrgSize);
 
      iErr = inflateEnd(&ZipStream);
 
      if (iErr != Z_OK)
      {
         printf("INFLATEEND Err %d,%s\n",ZipStream.msg);
      }
 
      CloseHandle(hFile);
      hFile = INVALID_HANDLE_VALUE;
   }  
 
   // Cleanup
   eBook.Close();
1
7792 / 6559 / 2984
Регистрация: 14.04.2014
Сообщений: 28,668
23.09.2015, 23:35 8
gazlan, просвети по поводу имён файлов.
0
3176 / 1935 / 312
Регистрация: 27.08.2010
Сообщений: 5,131
Записей в блоге: 1
23.09.2015, 23:59 9
Загадка о файле-невидимке
Атака на архиваторы. Скрываемся в одном архиве от трех программ
Спуфинг расширения в winrar

Не по теме:

P.S.

WebExe e-book. Книжка для тренировки: Юлий Клевер - Пародии на детские садистские стишки

1
56 / 50 / 22
Регистрация: 17.03.2014
Сообщений: 142
24.09.2015, 14:16  [ТС] 10
gazlan, спасибо, утром посмотрю

Добавлено через 13 часов 57 минут
gazlan, а что необходимо подключить для работоспособности кода в вашем примере?По умолчанию у меня не определяются MMF, функция QuickSearch и еще несколько идентификаторов.
0
3176 / 1935 / 312
Регистрация: 27.08.2010
Сообщений: 5,131
Записей в блоге: 1
24.09.2015, 15:32 11
Я использую собственные обертки к WinAPI.
Вложения
Тип файла: 7z full_project.7z (86.0 Кб, 82 просмотров)
0
24.09.2015, 15:32
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
24.09.2015, 15:32
Помогаю со студенческими работами здесь

Чтение архива RAR или ZIP (возможно с предварительно установленным паролем)
Доброго всем времени суток! такая вот задача: создать программу чтения фаилов из архива...

Распаковка архива zip
как распаковать архив .zip в дерикторию с программой?

Распаковка архива (.zip)
Нужно программно распаковать zip архив. Какие библиотеки могут это сделать ? Можно ли распаковать...

Распаковка ZIP-архива
Как с помощью bat, распаковать ZIP архив ? На одном форуме нашел for %i in (*.zip) do @(md...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
11
Ответ Создать тему
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2024, CyberForum.ru