Форум программистов, компьютерный форум, киберфорум
Visual Basic
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск  
 
 
Рейтинг 5.00/1: Рейтинг темы: голосов - 1, средняя оценка - 5.00
1412 / 876 / 93
Регистрация: 08.02.2017
Сообщений: 3,728
Записей в блоге: 2

Работа с zip архивами

29.10.2024, 02:49. Показов 24068. Ответов 283
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Из всего, что попадалось по теме сжатия/распаковки ZIP наиболее интересные были примеры с использованием библиотеки Zlib. Оригинальная zlib использует cdecl экспорт функций, но есть реализация zlibwapi.dll, которую можно использовать в VB. Вот хороший пример использования. Там можно увидеть как сжть/распаковать массив байтов, но вот беда, очень сложно найти пример под VB с более обширным использованием, способной на большее, данной либы, которая не есть простая, там есть функции с использованием множества параметров констант и длинных структур, которые чтобы узнать наверное надо долго копатся в сишных заголочниках. Но HackerVlad в личной беседе говорил, что у него есть исходники с использованием данной библиотеки, поэтому любезно прошу его поделиться данной информацией.

Добавлено через 1 минуту
кстати словосочетание zip-архивами в названии форум блочит почему-то )

Добавлено через 6 минут
На одном форуме есть хороший пример испльзования функций zlib для извлечения/распаковки отдельных файлов, там
Кликните здесь для просмотра всего текста
обсуждался какой-то экзотический ЯП Clarion, но очень наглядно
Code
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
! Источнег: https://forum.clarionlife.net/viewtopic.php?t=2389
! Для добавления в архив PwlZip ваш пароль
ZipHandle = zipOpen(NEW_ZIPPACK, 0)
If EncryptFlag = 1
Res# = zipOpenNewFileInZip3(ZipHandle, PATH_CURZIP, Zinfo, 0, 0, 0, 0, Comment, Z_DEFLATED, CompressionFlag,0,-15,8,0,PwlZip,0)
Else
Res# = zipOpenNewFileInZip(ZipHandle, PATH_CURZIP, Zinfo, 0, 0, 0, 0, Comment, Z_DEFLATED, CompressionFlag)
.
 
!Для чтения из архива
ZipHandle = unzOpen(PATH_INFILE_PACK)
LocRes1=UnzGoToFirstFile(ZipHandle)
If unzGetCurrentFileInfo(ZipHandle,FinFo,PATH_NAMEUPD_TMP,Size(PATH_NAMEUPD_TMP),0,0,Comment,Size(Comment)).
If FinFo.Flag = 3 !признак шифрованного zip по крайней мере так я понял после мыкания с архивами
LocRes2 = unzOpenCurrentFilePassword(ZipHandle,PwlZip)
Else
LocRes2 = UnzOpenCurrentFile(ZipHandle)

Здесь подробное описание функций, структур и констант, однако я не нашел там unzGetCurrentFileInfo и т.п.
0
Programming
Эксперт
39485 / 9562 / 3019
Регистрация: 12.04.2006
Сообщений: 41,671
Блог
29.10.2024, 02:49
Ответы с готовыми решениями:

Работа с ZIP-архивами - распаковка файлов
Привет, уважаемый ALL! Подскажите, как можно работать с zip архивами из VBA? Стоит задача: 1) прочитать из архива...

Автоматизировать заполнение "Графика выполненных работ по месяцам"
Используя готовую рабочую книгу Blank1.xls, автоматизировать заполнение "Графика выполненных работ по месяцам". Из диапазона дат в...

Задания из лаб.работ
Надоедаю наверное уже всем...

283
Вернулся
 Аватар для HackerVlad
1778 / 673 / 46
Регистрация: 10.09.2021
Сообщений: 2,820
30.10.2024, 17:52
Студворк — интернет-сервис помощи студентам
АААА всё вижу да ты сделал так что просто непонятно зачем автоматически распаковывать при создании списка, а не по отдельной команде/функции?
0
1412 / 876 / 93
Регистрация: 08.02.2017
Сообщений: 3,728
Записей в блоге: 2
30.10.2024, 18:02  [ТС]
Цитата Сообщение от HackerVlad Посмотреть сообщение
сам wqweto мне сказал что у него код распаковки медленнее
а в этом нет секрета, в Vb же нет оптимизации логических операций как в C, а зип-сжатие все на этом построено, я бы даже не проверял, зная это.

Добавлено через 3 минуты
Хотя возможно, если в твин-бейсике будут какие-то улучшения, то и его код будет быстрее, да он и в принципе наверное очень быстрый, если не здарачиваться с быстротой )
0
Вернулся
 Аватар для HackerVlad
1778 / 673 / 46
Регистрация: 10.09.2021
Сообщений: 2,820
30.10.2024, 18:03
testuser2, на самом деле оптимальным решением было бы распаковывать буфер с помощью встроенной в винду библиотеку zipfldr.dll но я не знаю как ей пользоваться, трюкач дал ссылку и на этом всё, его код не работает там
0
1412 / 876 / 93
Регистрация: 08.02.2017
Сообщений: 3,728
Записей в блоге: 2
30.10.2024, 18:23  [ТС]
Цитата Сообщение от HackerVlad Посмотреть сообщение
ты сделал так что просто непонятно зачем автоматически распаковывать при создании списка
Я cделал просто так, чтобы это было загадкой )

Добавлено через 6 минут
Цитата Сообщение от HackerVlad Посмотреть сообщение
библиотеку zipfldr.dll
с ней можно работать только имея oleexp.tlb, я видел примеры у fafalone также работы с этой библой

Добавлено через 11 минут
Вот пример распаковки от fafalone, он, кстати там пишет, что его код основан на другом сишном коде

Добавлено через 1 минуту
Честно, скажу, мне не очень нравятся такие примеры, для чертовой распаковки зипа столько непонятных вещей..
1
Модератор
10068 / 3913 / 886
Регистрация: 22.02.2013
Сообщений: 5,863
Записей в блоге: 79
30.10.2024, 18:51
testuser2, тот код что я давал работает с либой. На выходе никаких внешних зависимостей - прямая работа с zipfldr.
1
Вернулся
 Аватар для HackerVlad
1778 / 673 / 46
Регистрация: 10.09.2021
Сообщений: 2,820
31.10.2024, 01:39
testuser2, у fafalone действительно интересный пример, я тоже не очень люблю возиться с подключением TLB но иногда приходится. Но в том примере нет распаковки буфера в байтовый массив, только файлы.

Добавлено через 44 секунды
The trick, есть ли у zipfldr возможность распаковки буфера в байтовый массив?

Добавлено через 3 минуты
The trick, даже после того как я подключил oleexp.tlb всё равно твой пример не работает. Нету никаких ошибок но абсолютно ничего не происходит.

Добавлено через 4 минуты
The trick, теперь подключить решил olelib.tlb всё равно ничего не работает

Добавлено через 2 минуты
этот сырой пример от The Trick мне вообще никак не помог короче, у fafalone хотябы проект который уже работает

Добавлено через 5 часов 48 минут
Очень интересно оказалось на самом деле поработать с классом от wqweto у него в классе огромное количество возможностей, много разных свойств файлов можно получать, все вложенные подпапки, открывает архив под паролем и так далее и тому подобное. Работает как с байтовыми массивами так и просто с файлами, упаковка/распаковка, добавление, удаление - всё что угодно прям полноценная библиотека. Сейчас я проверяю как по скорости будет загружать на примере моей мини-программки для загрузки картинок и меня уже приятно удивило что работает быстро довольно.
1
1412 / 876 / 93
Регистрация: 08.02.2017
Сообщений: 3,728
Записей в блоге: 2
31.10.2024, 01:45  [ТС]
Еще она vba(x86)-совместимая я раньше проверял,тупо копируешь код в класс и работает
1
Вернулся
 Аватар для HackerVlad
1778 / 673 / 46
Регистрация: 10.09.2021
Сообщений: 2,820
31.10.2024, 01:52
В общем я пробовал файлы до 5 Мб правда только загружать из ZIP по скорости ни чем не хуже чем DLL реализация.
0
Вернулся
 Аватар для HackerVlad
1778 / 673 / 46
Регистрация: 10.09.2021
Сообщений: 2,820
31.10.2024, 01:56
В общем посмотри сам скорость достаточно быстрая в работе алгоритма wqweto, на удивление... Наверное он очень сильно постарался чтобы достичь максимальной скорости почти так же быстро как и в DLL
Миниатюры
Работа с zip архивами  
Вложения
Тип файла: zip example wqweto class.zip (19.13 Мб, 5 просмотров)
0
Вернулся
 Аватар для HackerVlad
1778 / 673 / 46
Регистрация: 10.09.2021
Сообщений: 2,820
31.10.2024, 02:06
И код довольно простой получается, вот посмотри:

Visual Basic
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
Option Explicit
Private Declare Function GetTickCount Lib "kernel32" () As Long
 
Private WithEvents m_oZip As cZipArchive
Private WithEvents m_oExtractInMemory As cZipArchive
 
Private Sub Command1_Click()
    Dim i As Long
    
    If List1.ListCount > 0 Then List1.Clear
    
    With m_oZip
        .OpenArchive App.Path & "\test.zip"
        
        For i = 0 To .FileCount - 1
            List1.AddItem .FileInfo(i, zipIdxFileName) & "    " & .FileInfo(i, zipIdxSize) & " bytes"
        Next
        
        Label1.Caption = "Count files: " & .FileCount
    End With
    
    List1.Selected(0) = True
    List1.SetFocus
End Sub
 
Private Sub List1_Click()
    Dim bytesData() As Byte
    Dim tick As Long
    
    tick = GetTickCount
    
    If m_oZip.Extract(bytesData, List1.ListIndex) = True Then
        Label2.Caption = "ml: " & GetTickCount - tick
        Picture1.Picture = PictureFromBits(bytesData)
    End If
End Sub
 
Private Sub Form_Load()
    Set m_oZip = New cZipArchive
End Sub
 
Private Sub Form_Unload(Cancel As Integer)
    Set m_oZip = Nothing
End Sub
Добавлено через 1 минуту
Хочу обратить внимание, что здесь я учитываю только скорость самой распаковки файла, скорость загрузки в пикчебокс я уже не учитываю это дополнительное время. То есть чисто распаковка даже больших файлов идёт довольно быстро, лишь чуть-чуть уступая скорости алгоритма DLL.

Добавлено через 4 минуты
То есть возиться с zipfldr нет никакого смысла вообще. Если прям супер огромные данные ты будешь распаковывать тогда используй технологию zlibwapi.dll будет немного быстрее. А если не сильно большие то класс от wqweto это просто то что нужно это просто сказка)

Добавлено через 1 минуту
Стоит только понимать, что при подключении этого класса EXE-файл будет увеличиваться на 150 Кб, но например zlibwapi.dll у тебя целых 170 Кб, даже больше немного...

Добавлено через 36 секунд
Хотя моя, более старая, версия zlibwapi.dll занимает всего 74 Кб
0
1412 / 876 / 93
Регистрация: 08.02.2017
Сообщений: 3,728
Записей в блоге: 2
31.10.2024, 02:13  [ТС]
Цитата Сообщение от HackerVlad Посмотреть сообщение
теперь подключить решил olelib.tlb всё равно ничего не работает
У меня работает, я подключил olelib.tlb 2014 года. Там файлы сначала копируются в байтовый массив, перед записью на дизк.
0
Вернулся
 Аватар для HackerVlad
1778 / 673 / 46
Регистрация: 10.09.2021
Сообщений: 2,820
31.10.2024, 02:18
Цитата Сообщение от testuser2 Посмотреть сообщение
У меня работает, я подключил olelib.tlb 2014 года.
Не знаю почему, но у меня не работает вообще код от The Trick, и я не вижу дальше смысла в этом разбираться - это неудобный способ по моему вообще. Не вижу смысла дальше продолжать работать в этом направлении вообще, мы итак уже всё разобрали по косточкам. Найдено два самых лучших решения это zlibwapi.dll и класс от wqweto. Всё, по моему тут дальше уже не стоит этим заниматься вообще.
0
1412 / 876 / 93
Регистрация: 08.02.2017
Сообщений: 3,728
Записей в блоге: 2
31.10.2024, 03:39  [ТС]
Есть еще вриант с 7zip библой )
0
Вернулся
 Аватар для HackerVlad
1778 / 673 / 46
Регистрация: 10.09.2021
Сообщений: 2,820
31.10.2024, 17:20
Несмотря на то, что я прекратил этим заниматься, тема получила дальнейшее развитие. На иностранном форуме я создавал тему с вопросом как распаковать ZIP библиотекой zlibwapi.dll. Вот эта тема: https://www.vbforums.com/showt... &p=5661070

Я там так же выкладывал свою мини-программку для чтения картинок из архива. Так вот китаец по имени xiaoyao обратил внимание на то, что класс любезно предоставленный Arnoutdv оказался недоработанным и не производилось чтение файлов из вложенных подпапок оказывается. xiaoyao решил сам доработать этот класс и сам создал новый код, новый форк так сказать, и выложил новую программку. Так же он добавил возможность распаковки в файлы.

Ещё он сделал вторую программу которая работает полностью на алгоритме zlibwapi. Здесь он выложил в готовых решениях даже как продолжение этой темы: https://www.vbforums.com/showt... ibwapi-dll
0
Вернулся
 Аватар для HackerVlad
1778 / 673 / 46
Регистрация: 10.09.2021
Сообщений: 2,820
31.10.2024, 17:31
Он доработал класс zlibwapiClass.cls вот новый код (в этом классе идёт только распаковка через zlibwapi.dll, а само чтение списка файлов из ZIP идёт самописными скриптами):

Visual Basic
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
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
Option Explicit
'OldName:clsZipExtractionClass
'by xiaoyao / HackerVlad
 
Private Declare Function MakeSureDirectoryPathExists Lib "imagehlp" (ByVal PathName As String) As Long
Private m_fID As Integer
Private m_bOpenZip As Boolean
 
 
Private Const INVALID_HANDLE_VALUE As Long = -1
Private Const OPEN_EXISTING  As Long = 3
Private Const FILE_SHARE_READ  As Long = &H1
Private Const FILE_SHARE_WRITE  As Long = &H2
Private Const GENERIC_WRITE  As Long = &H40000000
Private Const GENERIC_READ As Long = &H80000000
Private Const FILE_ATTRIBUTE_NORMAL As Long = &H80
Private Const MAX_PATH As Long = 260
 
 
Private Type FILETIME
  dwLowDateTime As Long
  dwHighDateTime As Long
End Type
 
'Private Type SYSTEMTIME
'  Year As Integer
'  Month As Integer
'  DayOfWeek As Integer
'  Day As Integer
'  Hour As Integer
'  Minute As Integer
'  Second As Integer
'  Milliseconds As Integer
'End Type
 
Private Type WIN32_FIND_DATA
   dwFileAttributes As Long
   ftCreationTime As FILETIME
   ftLastAccessTime As FILETIME
   ftLastWriteTime As FILETIME
   nFileSizeHigh As Long
   nFileSizeLow As Long
   dwReserved0 As Long
   dwReserved1 As Long
   cFileName As String * MAX_PATH
   cAlternate As String * 14
End Type
 
 
Private Declare Function CopyMemory Lib "kernel32" Alias "RtlMoveMemory" (Dest As Any, src As Any, ByVal Length As Long) As Long
Private Declare Function lstrcpy Lib "kernel32" Alias "lstrcpyA" (ByVal lpBuffer As String, ByVal lpString As Long) As Long
Private Declare Function lstrlen Lib "kernel32" Alias "lstrlenA" (ByVal lpString As Long) As Long
 
Private Declare Function ZLibVer Lib "zlibwapi.dll" Alias "zlibVersion" () As Long
'Private Declare Function Compress Lib "zlibwapi.dll" Alias "compress" (Dest As Any, destLen As Any, src As Any, ByVal srcLen As Long) As Long
'Private Declare Function Compress2 Lib "zlibwapi.dll" Alias "compress2" (Dest As Any, destLen As Any, src As Any, ByVal srcLen As Long, ByVal Level As Long) As Long
Private Declare Function Uncompress Lib "zlibwapi.dll" Alias "uncompress" (Dest As Any, destLen As Any, src As Any, ByVal srcLen As Long) As Long
Private Declare Function lCRC32 Lib "zlibwapi.dll" Alias "crc32" (ByVal Crc As Long, Buffer As Any, ByVal Length As Long) As Long
 
Private Declare Function DosDateTimeToFileTime Lib "kernel32.dll" (ByVal wFatDate As Long, ByVal wFatTime As Long, lpFileTime As FILETIME) As Long
Private Declare Function LocalFileTimeToFileTime Lib "kernel32.dll" (lpLocalFileTime As FILETIME, lpFileTime As FILETIME) As Long
 
Private Declare Function SetFileTime Lib "kernel32" (ByVal hFile As Long, CreationTime As FILETIME, LastAccessTime As FILETIME, LastWriteTime As FILETIME) As Long
 
Private Declare Function CreateFile Lib "kernel32" Alias "CreateFileA" (ByVal lpFileName As String, ByVal dwDesiredAccess As Long, ByVal dwShareMode As Long, ByVal lpSecurityAttributes As Long, ByVal dwCreationDisposition As Long, ByVal dwFlagsAndAttributes As Long, ByVal hTemplateFile As Long) As Long
Private Declare Function CloseHandle Lib "kernel32" (ByVal hObject As Long) As Long
 
Private Declare Function FindFirstFile Lib "kernel32" Alias "FindFirstFileA" (ByVal lpFileName As String, lpFindFileData As WIN32_FIND_DATA) As Long
Private Declare Function FindClose Lib "kernel32" (ByVal hFindFile As Long) As Long
 
                 
Public Enum eZipError
  zeZLibNotInstalled = 1
  zeNotZipFile = 2
  zeNoOpenZipFile = 3
  zeUnsupportedCompressionMethod = 4
  zeChecksumError = 5
  zeFileNotFound = 10
  zeFileAlreadyExists = 11
  zeCantRemoveFile = 12
  zeCantCreateFolder = 13
  zeCantCreateFile = 14
End Enum
 
 
Private Type typCentralFileHeader
    CentralFileHeaderSigniature As Long
    VersionMadeBy As Integer
    VersionNeededToExtract As Integer
    GeneralPurposeBitFlag As Integer
    CompressionMethod As Integer
    LastModFileTime As Integer
    LastModFileDate As Integer
    CRC32 As Long
    CompressedSize As Long
    UnCompressedSize As Long
    FileNameLength As Integer
    ExtraFieldLength As Integer
    FileCommentLength As Integer
    DiskNumberStart As Integer
    InternalFileAttributes As Integer
    ExternalFileAttributes As Long
    RelativeOffsetOfLocalHeader As Long
'    FileName As Long              'ОДјюГы
'    ExtraField As Long            'ёЅјУРЕПў
'    Comment As Long               'ОДјюёЅЧў
End Type
 
'EndOfCentralDirectory
Private Type typCenteralDirEnd
  EndOFCentralDirSignature As Long
  NumberOfThisDisk As Integer
  NumberOfDiskWithCentralDir As Integer
  EntriesInTheCentralDirThisOnDisk As Integer
  EntriesInTheCentralDir As Integer
  SizeOfCentralDir As Long
  OffSetOfCentralDir As Long
  ZipFileCommentLength As Integer
End Type
 
Private Type typLocalFileHeader
  LocalFileHeaderSignature As Long
  VersionNeededToExtract As Integer
  GeneralPurposeBitFlag As Integer
  CompressionMethod As Integer
  LastModFileTime As Integer
  LastModFileDate As Integer
  CRC32 As Long
  CompressedSize As Long
  UnCompressedSize As Long
  FileNameLength As Integer
  ExtraFieldLength As Integer
End Type
 
Private Const EndOFCentralDirSignature As Long = &H6054B50
Private Const CentralFileHeaderSigniature As Long = &H2014B50
Private Const LocalFileHeaderSignature As Long = &H4034B50
 
Private CentralFileHeader As typCentralFileHeader
Private CentralDirEnd As typCenteralDirEnd
 
Private CentralDirEndPos As Long
 
Public Event Progress(Percent As Long, Cancel As Boolean)
Public Event Status(Text As String)
Public Event ZipError(Number As eZipError, Description As String)
 
Public Property Get ZLibVersion() As String
  On Error GoTo errHandler
  
  ZLibVersion = PointerToString(ZLibVer)
  Exit Property
 
errHandler:
MsgBox "Zlib is not installed"
   RaiseEvent ZipError(zeZLibNotInstalled, "Zlib is not installed")
End Property
 
Public Function OpenZip(ZipPath As String) As Boolean
 
  m_bOpenZip = False
  
  RaiseEvent Status("Opening Zip")
  CloseZip
 
  If Not FileExists(ZipPath) Then
    RaiseEvent ZipError(zeFileNotFound, "The file " & ZipPath & " doesn't exist")
    Exit Function
  End If
 
  m_fID = FreeFile
  Open ZipPath For Binary As #m_fID
  
  CentralDirEndPos = GetCentralDirEndPos(m_fID)
  If CentralDirEndPos > 0 Then
    m_bOpenZip = True
    OpenZip = True
    RaiseEvent Status("Zip Opened")
  Else
    RaiseEvent ZipError(zeNotZipFile, "The file " & ZipPath & " is not a Zip file")
  End If
   
End Function
 
Public Sub CloseZip()
  If m_fID <> 0 Then
     Close #m_fID
     m_fID = 0
     RaiseEvent Status("Zip Closed")
  End If
  CentralDirEndPos = 0
  
End Sub
 
Public Property Get Files() As Collection
  Dim l As Long
  Dim sFilename As String
  
  Set Files = New Collection
  
  If m_bOpenZip Then
    If ReadCentralDirEnd(CentralDirEndPos) Then
      
      Seek #m_fID, CentralDirEnd.OffSetOfCentralDir + 1
      For l = 1 To CentralDirEnd.EntriesInTheCentralDir
        ReadCentralFileHeader sFilename
        Files.Add sFilename, sFilename
        
        'Seek #m_fID, LenB(CentralDirEnd)
      Next l
    End If
  End If
  
End Property
 
'---------------------------------------------------------------------------------------
' Procedure : ExtractToFolder
' DateTime  : 2024-10-31
' Author    : xiaoyao (china)
'---------------------------------------------------------------------------------------
Public Function ExtractToFolder(ToFolder As String, Optional ByVal FolderOrFile As String = "*", Optional ByRef SaveFileCount As Long) As Boolean
'FolderOrFile=1.jpg or folder1\2.jpg or *.pdf
'FolderOrFile= folder1\*  (Extract path:folder1\)
'FolderOrFile="*", Extract all Folder and Files
  Dim l As Long
  Dim FilePos As Long
  Dim sFilename As String, bData() As Byte
   
  If Len(ZLibVersion) = 0 Then
     Exit Function
  End If
  Dim DiskFile As String, FilePath As String
  If CentralDirEndPos = 0 Then
    RaiseEvent ZipError(zeNoOpenZipFile, "There is no Zip File Open")
    Exit Function
  End If
   
  FolderOrFile = LCase$(FolderOrFile)
  Dim iseek As Long
     
  Dim ToMemoryOK As Boolean
  If ReadCentralDirEnd(CentralDirEndPos) Then
    Seek #m_fID, CentralDirEnd.OffSetOfCentralDir + 1
    
    For l = 1 To CentralDirEnd.EntriesInTheCentralDir
      ReadCentralFileHeader sFilename
      sFilename = LCase(Replace(sFilename, "/", "\"))
      If sFilename Like FolderOrFile Then
         DiskFile = ToFolder & sFilename
      'If LCase$(GetFileName(sFilename)) = FolderOrFile Then
        If Right(sFilename, 1) = "\" Then        'IS FOLDER
            MakeLongDir DiskFile
        Else
            FilePos = Seek(m_fID)
            'Debug.Print sFilename & ",FileSizeЈє" & CentralFileHeader.UnCompressedSize
            If CentralFileHeader.UnCompressedSize > 0 Then
                
                ToMemoryOK = ExtractArray(sFilename, bData)
              Else
              ReDim bData(-1 To -1)
            End If
               
                FilePath = Left(DiskFile, InStr(DiskFile, "\"))
                MakeLongDir FilePath
                PutToFileBin DiskFile, bData
                SaveFileCount = SaveFileCount + 1
                'RE SET FILE Pointer For Read Next Zip FileInfo
                Seek #m_fID, FilePos
        End If
        
      End If
    Next l
  End If
End Function
Function PutToFileBin(filename As String, bin() As Byte) As Boolean
   '[mycode_id:1940],edittime:2011/7/12 0:04:11
   On Error Resume Next
   Kill filename
   On Error GoTo Err
       Dim hFile As Integer
       hFile = FreeFile
       Open filename For Binary As #hFile
       Put #hFile, , bin
       Close #hFile
       PutToFileBin = True
   Exit Function
Err:
       MsgBox Err.Description
End Function
'---------------------------------------------------------------------------------------
' Procedure : ExtractToMemory
' DateTime  : 18-11-2006
' Author    : ArnoutV
' Purpose   :
'---------------------------------------------------------------------------------------
Public Function ExtractToMemory(ByVal sExtractFile As String, bData() As Byte) As Boolean
  Dim l As Long
  Dim FilePos As Long
  Dim sFilename As String
   
  If Len(ZLibVersion) = 0 Then
     Exit Function
  End If
   
  If CentralDirEndPos = 0 Then
    RaiseEvent ZipError(zeNoOpenZipFile, "There is no Zip File Open")
    Exit Function
  End If
   
  sExtractFile = LCase$(sExtractFile)
  
  If ReadCentralDirEnd(CentralDirEndPos) Then
    Seek #m_fID, CentralDirEnd.OffSetOfCentralDir + 1
    
    For l = 1 To CentralDirEnd.EntriesInTheCentralDir
      ReadCentralFileHeader sFilename
      sFilename = LCase(Replace(sFilename, "/", "\"))
      If sFilename = sExtractFile Then
      'If LCase$(GetFileName(sFilename)) = sExtractFile Then
        If CentralFileHeader.UnCompressedSize > 0 Then
          FilePos = Seek(m_fID)
          ExtractToMemory = ExtractArray(sFilename, bData)
          Else
          ReDim bData(-1 To -1)
        End If
        Exit For
      End If
    Next l
  End If
End Function
Public Function GetFiles() As String()
  Dim l As Long
  Dim sFilename As String
  Dim aTemp() As String
  
  If m_bOpenZip Then
    If ReadCentralDirEnd(CentralDirEndPos) Then
      ReDim aTemp(CentralDirEnd.EntriesInTheCentralDir - 1)
      
      Seek #m_fID, CentralDirEnd.OffSetOfCentralDir + 1
      For l = 1 To CentralDirEnd.EntriesInTheCentralDir
        ReadCentralFileHeader sFilename
        aTemp(l - 1) = sFilename
      Next l
    End If
  End If
  
  GetFiles = aTemp
End Function
 
'Public Function GetFilesFixed() As String()
''MsgBox "err:"
'
'  Dim aTemp() As String
'
'  Dim I As Long
'  Dim FilePos As Long
'  Dim sFilename As String
'
'  If Len(ZLibVersion) = 0 Then
'     Exit Function
'  End If
'
'  If CentralDirEndPos = 0 Then
'    RaiseEvent ZipError(zeNoOpenZipFile, "There is no Zip File Open")
'    ReDim aTemp(-1 To -1)
'     GetFilesFixed = aTemp
'    Exit Function
'  End If
'
'
'
'  If ReadCentralDirEnd(CentralDirEndPos) Then
'    ReDim aTemp(CentralDirEnd.EntriesInTheCentralDir - 1)
'
'    Seek #m_fID, CentralDirEnd.OffSetOfCentralDir + 1
'    For I = 1 To CentralDirEnd.EntriesInTheCentralDir
'
'      ReadCentralFileHeader sFilename
'       aTemp(I - 1) = sFilename
'
'        ' Seek #m_fID, CentralDirEnd.OffSetOfCentralDir
'    Next I
'  End If
'  GetFilesFixed = aTemp
'End Function
 
'    Dim iseek As Long
'    iseek = VBA.Seek(m_fID)
'    Debug.Print "iseek=" & iseek
    
Private Sub ReadCentralFileHeader(filename As String)
  Dim ExtraField As String
  Dim Comment As String
   Dim iseek As Long
  filename = ""
  iseek = VBA.Seek(m_fID)
  'Debug.Print "РВЅЪµДО»ЦГЈєiseek=" & iseek
  Get #m_fID, , CentralFileHeader
  
  If CentralFileHeader.CentralFileHeaderSigniature = CentralFileHeaderSigniature Then
    
    filename = ReadStrByLen(CentralFileHeader.FileNameLength)
    filename = Replace(filename, "/", "\")
    
 
      iseek = iseek + Len(CentralFileHeader) + CentralFileHeader.FileNameLength + CentralFileHeader.ExtraFieldLength + CentralFileHeader.FileCommentLength
     Seek m_fID, iseek
     'Debug.Print "Т»ёцОДјюРЕПўМбИЎНкіЙЈ¬МшµЅЈє" & LastSeek
    'ExtraField = ReadStrByLen(CentralFileHeader.ExtraFieldLength)
    'Comment = ReadStrByLen(CentralFileHeader.FileCommentLength)
'  FileName = PointerToString2(CentralFileHeader.FileName, CentralFileHeader.FileNameLength)
'  ExtraField = PointerToString2(CentralFileHeader.ExtraField, CentralFileHeader.ExtraFieldLength)
'  Comment = PointerToString2(CentralFileHeader.Comment, CentralFileHeader.FileCommentLength)
 
'    FileName = Space(CentralFileHeader.FileNameLength)
'    Get #m_fID, , FileName
    'FileName = Replace(FileName, "/", "\")
'    ExtraField = Space(CentralFileHeader.ExtraFieldLength)
'    Get #m_fID, , ExtraField
'    Comment = Space(CentralFileHeader.FileCommentLength)
'    Get #m_fID, , Comment
Else
 
  End If
 
End Sub
 
Public Function Count() As Long
  If m_bOpenZip Then
    Count = CentralDirEnd.EntriesInTheCentralDir
  Else
    Count = -1
  End If
End Function
 
 
 
Private Function GetFileName(Path As String) As String
  Dim l As Long
  
  l = InStrRev(Path, "\")
  If l > 0 Then GetFileName = Right$(Path, Len(Path) - l) Else GetFileName = Path
   
End Function
 
Private Function GetFilePath(Path As String) As String
 Dim l As Long
 
 l = InStrRev(Path, "\")
 If l > 0 Then GetFilePath = Left$(Path, l - 1)
   
End Function
 
 
Function ReadStrByLen(Len1 As Integer) As String
 Dim Buffer() As Byte
 If Len1 = 0 Then Exit Function
  ReDim Buffer(Len1 - 1)
  Get #m_fID, , Buffer
  ReadStrByLen = StrConv(Buffer, vbUnicode)
End Function
 
Private Function ReadCentralDirEnd(Position As Long) As Boolean
  Dim ZipComment As String
  
  Get #m_fID, Position, CentralDirEnd
  ZipComment = Space(CentralDirEnd.ZipFileCommentLength)
  Get #m_fID, , ZipComment
  
  ReadCentralDirEnd = CentralDirEnd.NumberOfThisDisk = CentralDirEnd.NumberOfDiskWithCentralDir
End Function
 
'---------------------------------------------------------------------------------------
' Procedure : ExtractArray
' DateTime  : 18-11-2006
' Author    : ArnoutV
' Purpose   :
'---------------------------------------------------------------------------------------
Private Function ExtractArray(Path As String, b() As Byte) As Boolean
  'ExtractArray NowFile
  Dim LocalFileHeader As typLocalFileHeader
  Dim sFilename As String
  Dim sExtraField As String
 
  Get #m_fID, CentralFileHeader.RelativeOffsetOfLocalHeader + 1, LocalFileHeader
  If LocalFileHeader.LocalFileHeaderSignature = LocalFileHeaderSignature Then
    Dim iseek As Long
     iseek = VBA.Seek(m_fID)
'    sFilename = Space(LocalFileHeader.FileNameLength)
'    Get #m_fID, , sFilename
'    sExtraField = Space(LocalFileHeader.ExtraFieldLength)
'    Get #m_fID, , sExtraField
    
    Seek #m_fID, iseek + LocalFileHeader.FileNameLength + LocalFileHeader.ExtraFieldLength
    
 
    iseek = VBA.Seek(m_fID)
    Debug.Print "iseek=" & iseek
 
    ReDim b(LocalFileHeader.CompressedSize - 1)
    Get #m_fID, , b
    If CentralFileHeader.CompressionMethod = 0 Then
      'No Compression
      ExtractArray = True
    ElseIf CentralFileHeader.CompressionMethod = 8 Then 'Deflate Method
      If UnCompressBytes(b, LocalFileHeader.CompressedSize, LocalFileHeader.UnCompressedSize, LocalFileHeader.CRC32) Then
        ExtractArray = True
      Else
        RaiseEvent ZipError(zeChecksumError, "Data checksum error in " & Path)
      End If
    Else
      RaiseEvent ZipError(zeUnsupportedCompressionMethod, "The compression Method for " & sFilename & " is unsupported")
    End If
  End If
   
End Function
 
Private Function GetCentralDirEndPos(fID As Integer) As Long
 
  Dim bData() As Byte
  Dim l As Long
  Dim m As Long
 
  ReDim bData(LOF(fID) - 1)
  Get #fID, , bData
  
  For l = UBound(bData) - 3 To LBound(bData) Step -1
    CopyMemory m, bData(l), 4
    If m = EndOFCentralDirSignature Then
      GetCentralDirEndPos = l + 1
      Exit Function
    End If
  Next
 
End Function
 
Private Function UnCompressBytes(Buffer() As Byte, CompressedSize As Long, UnCompressedSize As Long, CRC32 As Long) As Boolean
   
  Dim b() As Byte
 
  Dim BufferSize As Long
  Dim FileSize As Long
  
  Dim DecompressCRC32 As Long
  Dim R As Long
 
  ReDim b(UBound(Buffer) + 2)
  
  'Zlib's Uncompress method expects the 2 byte head that the Compress method adds
  'so we put that on first. Luckily it's always the same value.
  b(0) = 120
  b(1) = 156
  CopyMemory b(2), Buffer(0), UBound(Buffer) + 1
 
  FileSize = UBound(Buffer) + 3
  BufferSize = CentralFileHeader.UnCompressedSize * 1.01 + 12
  ReDim Buffer(BufferSize - 1) As Byte
  
  R = Uncompress(Buffer(0), BufferSize, b(0), FileSize)
 
  ReDim Preserve Buffer(CentralFileHeader.UnCompressedSize - 1)
  DecompressCRC32 = lCRC32(0&, Buffer(0), UBound(Buffer) + 1)
  If DecompressCRC32 = CRC32 Then
    UnCompressBytes = True
  End If
 
End Function
 
Private Function PointerToString(Pointer As Long) As String
  Dim l As Long
  Dim s As String
  
  l = lstrlen(Pointer)
  s = Space(l)
  l = lstrcpy(s, Pointer)
  If l > 0 Then
     PointerToString = s
  End If
  
End Function
 
Private Function FileExists(sSource As String) As Boolean
 
  Dim WFD As WIN32_FIND_DATA
  Dim hFile As Long
  
  hFile = FindFirstFile(sSource, WFD)
  FileExists = hFile <> INVALID_HANDLE_VALUE
  
  Call FindClose(hFile)
   
End Function
 
Private Sub Class_Terminate()
  CloseZip
End Sub
Function MakeLongDir(ByVal PathToDest As String) As Boolean
    'ЅЁБў¶ај¶ЧУДїБй
    Dim R As Long
    PathToDest = Replace(PathToDest, "/", "\")
    If Right(PathToDest, 1) <> "\" Then PathToDest = PathToDest & "\"
    MakeLongDir = MakeSureDirectoryPathExists(PathToDest)
End Function
Вложения
Тип файла: zip zlibwapi_UnzipToFolder.zip (694.7 Кб, 5 просмотров)
1
Вернулся
 Аватар для HackerVlad
1778 / 673 / 46
Регистрация: 10.09.2021
Сообщений: 2,820
31.10.2024, 17:35
Потом этот китаец так же немного переделал класс MiniZipDir и выложил тоже программку новую с этим классом.
В этом классе используется только код чтения и распаковки исключительно из API-функций к zlibwapi.dll.

Visual Basic
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
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
Option Explicit
'==========
'MiniZipDir version 2
'==========
'
'Minimal interface to minilib (in zlibwapi.dll) for querying the directory in a Zip archive.
'This returns the item's Name and CRC as stored in the Zip archive.
'
'Put zlibwapi.dll into the Project's (EXE's) folder.
'
'NOTES
'
'   o Paths to Zip files to be queried must be absolute, full-qualified paths.  It doesn't
'     find them if you try to look up by relative path.
'
'   o The String values in and out are in theory ANSI but may well actually be codepage 437
'     DOS OEM extended ASCII.  However a lot of Zip archive creation software probably just
'     jams ANSI in there under the current codepage.
'
'     In theory there is also UTF-8 support but that probably is only true for leter versions
'     of the Zip format.  Or perhaps only for Zip64 format?
'
'   o Directory separators come back as "/" and not "\" but we could easily replace those
'     here.  I'm not sure why they do this though.  I had assumed Zip format originated on
'     MS-DOS, but true or not perhaps "/" was put in back then to be universal, or perhaps
'     this is something that "minilib" is doing?
'
 
Private Const WIN32_NULL As Long = 0
 
Private Const MAX_PATH As Long = 260
 
Private Const Z_ERRNO As Long = -1
 
Private Const UNZ_NULL As Long = 0
 
Public Enum UnzipResults
    UNZ_OK = 0
    UNZ_END_OF_LIST_OF_FILE = -100
    UNZ_ERRNO = Z_ERRNO
    UNZ_EOF = 0
    UNZ_PARAMERROR = -102
    UNZ_BADZIPFILE = -103
    UNZ_INTERNALERROR = -104
    UNZ_CRCERROR = -105
    UNZ_ALREADYOPEN = -500 'Private extension.
    UNZ_OPENFAILED = -501 'Private extension.
    UNZ_NOTOPEN = -502 'Private extension.
End Enum
#If False Then
Dim UNZ_OK, UNZ_END_OF_LIST_OF_FILE, UNZ_ERRNO, UNZ_EOF, UNZ_PARAMERROR, UNZ_BADZIPFILE
Dim UNZ_INTERNALERROR, UNZ_CRCERROR, UNZ_ALREADYOPEN
#End If
 
Private Type tm_unz
    tm_sec As Long                  'seconds after the minute - [0,59]
    tm_min As Long                  'minutes after the hour - [0,59]
    tm_hour As Long                 'hours since midnight - [0,23]
    tm_mday As Long                 'day of the month - [1,31]
    tm_mon As Long                  'months since January - [0,11]
    tm_year As Long                 'years - [1980..2044]
End Type
 
Private Type unz_file_info
    version As Long                 'version made by                 2 bytes
    version_needed As Long          'version needed to extract       2 bytes
    flag As Long                    'general purpose bit flag        2 bytes
    compression_method As Long      'compression method              2 bytes
    dosDate As Long                 'last mod file date in Dos fmt   4 bytes
    Crc As Long                     'crc-32                          4 bytes
    compressed_size As Long         'compressed size                 4 bytes
    uncompressed_size As Long       'uncompressed size               4 bytes
    size_filename As Long           'filename length                 2 bytes
    size_file_extra As Long         'extra field length              2 bytes
    size_file_comment As Long       'file comment length             2 bytes
    disk_num_start As Long          'disk number start               2 bytes
    internal_fa As Long             'internal file attributes        2 bytes
    external_fa As Long             'external file attributes        4 bytes
    tmu_date As tm_unz
End Type
 
Private Declare Function unzOpen Lib "zlibwapi" ( _
    ByVal Path As String) As Long
Private Declare Function unzClose Lib "zlibwapi" ( _
    ByVal unzhFile As Long) As UnzipResults
Private Declare Function unzGoToFirstFile Lib "zlibwapi" ( _
    ByVal unzhFile As Long) As UnzipResults
Private Declare Function unzGoToNextFile Lib "zlibwapi" ( _
    ByVal unzhFile As Long) As UnzipResults
Private Declare Function unzReadCurrentFile Lib "zlibwapi" ( _
    ByVal unzhFile As Long, ByVal BufferPtr As Long, ByVal Size As Long) As UnzipResults
Private Declare Function unzOpenCurrentFile Lib "zlibwapi.dll" (ByVal unzhFile As Long) As Long
Private Declare Function unzCloseCurrentFile Lib "zlibwapi.dll" (ByVal unzhFile As Long) As Long
 
Private Declare Function unzGetCurrentFileInfo Lib "zlibwapi" ( _
    ByVal unzhFile As Long, _
    ByVal pFileInfo As Long, _
    ByVal FileName As String, _
    ByVal FileNameBufferSize As Long, _
    ByVal pExtraField As Long, _
    ByVal ExtraFieldBufferSize As Long, _
    ByVal Comment As String, _
    ByVal CommentBufferSize As Long) As UnzipResults
 
Private unzhFile As Long 'Unzip handle to an open archive.
 
Private mEndOfFiles As Boolean
Private mUnzResults As UnzipResults
 
Public Property Get EndOfFiles() As Boolean
    EndOfFiles = mEndOfFiles
End Property
 
Public Property Get UnzResults() As UnzipResults
    UnzResults = mUnzResults
End Property
Function FindFile(ByVal zipChildFileName As String, Optional FileSize As Long, Optional Crc As Long) As Boolean
    'Exists(ChildFile) 'by xiaoyao #abcd
    Dim Ret As UnzipResults, FindFileOK As Boolean
    zipChildFileName = LCase(zipChildFileName)
    zipChildFileName = Replace(zipChildFileName, "\", "/")
    If unzhFile = UNZ_NULL Then
        mUnzResults = UNZ_NOTOPEN
        Err.Raise &H80045508, TypeName(Me), "Not open"
    End If
    Dim FileName As String
        Ret = unzGoToFirstFile(unzhFile)
    Do While Ret = UNZ_OK
        GetCurrentFileInfo FileName, Crc, FileSize
        If zipChildFileName = LCase(FileName) Then
            FindFile = True
            Exit Do
        End If
        Ret = unzGoToNextFile(unzhFile)
    Loop
End Function
Function ReadFileByte(ByVal zipChildFileName As String, Buffer() As Byte) As Boolean
 'by xiaoyao #abcd
    Dim Ret As UnzipResults, FileSize As Long
    If FindFile(zipChildFileName, FileSize) Then
        ReadFileByte = True
        If FileSize > 0 Then
            FileSize = FileSize
            ReDim Buffer(FileSize - 1)
            Ret = unzOpenCurrentFile(unzhFile)
            If Ret = UNZ_OK Then 'BufferPtr
                Ret = unzReadCurrentFile(unzhFile, VarPtr(Buffer(0)), FileSize) 'Result is FileByte
                If Ret <> FileSize Then
                    If Ret > 0 Then
                        ReDim Preserve Buffer(Ret - 1)
                    Else
                        ReDim Buffer(-1 To -1)
                    End If
                End If
                
            End If
            
             unzCloseCurrentFile unzhFile
        Else
            ReDim Buffer(-1 To -1)
        End If
        
    End If
End Function
Function UnzipAll(Folder As String) As Boolean 'by xiaoyao #abcd
    'unzip all file to a folder
    MsgBox "please add code"
End Function
Function UnzipChildFolder(Folder As String) As Boolean 'by xiaoyao #abcd
    'unzip a Child Folder from zip a Disk folder
    MsgBox "please add code"
End Function
Function UnzipToFile(ByVal zipChildFileName As String) As Boolean
 'by xiaoyao #abcd
    Dim Ret As Long, Buffer() As Byte
    If ReadFileByte(zipChildFileName, Buffer) Then
        UnzipToFile = PutToFileBin(zipChildFileName, Buffer)
    End If
End Function
 
Function PutToFileBin(FileName As String, bin() As Byte) As Boolean
   '[mycode_id:1940],edittime:2011/7/12 0:04:11
   On Error Resume Next
   Kill FileName
   On Error GoTo Err
       Dim hFile As Integer
       hFile = FreeFile
       Open FileName For Binary As #hFile
       Put #hFile, , bin
       Close #hFile
       PutToFileBin = True
   Exit Function
Err:
       MsgBox Err.Description
End Function
 
Sub GetFileList(FileList() As String, FileSizeArr() As Long, CrcArr() As Long)
 'by xiaoyao #abcd
    Dim Crc As Long
    Dim Path As String, FileSize As Long
    Dim Listc As New Dictionary
    Dim CrcDc As New Dictionary
    Dim FindFileOK As Boolean
    FindFileOK = ListFile(Path, Crc, FileSize, FindFileOK)
    Do While FindFileOK
        Listc.Add Path, FileSize
        CrcDc.Add Path, Crc
        FindFileOK = ListFile(Path, Crc, FileSize, FindFileOK)
    Loop
'    FirstFile Path, crc
'    Do While Len(Path)
'        Listc.Add Path
'        NextFile Path, crc
'    Loop
Dim ub As Long, I As Long
    ub = Listc.Count - 1
    If ub > -1 Then
        ReDim FileList(ub)
        ReDim FileSizeArr(ub)
        ReDim CrcArr(ub)
        Dim v
        With Listc
        For I = 0 To ub
            FileList(I) = .Keys(I)
            FileSizeArr(I) = .Items(I)
            CrcArr(I) = CrcDc.Items(I)
        Next
        End With
    Else
        ReDim FileSizeArr(-1 To -1)
        ReDim FileList(-1 To -1)
        ReDim CrcArr(-1 To -1)
    End If
End Sub
Public Sub CloseZip()
    Dim NewUnzResults As UnzipResults
 
    If unzhFile <> UNZ_NULL Then
        NewUnzResults = unzClose(unzhFile)
        If NewUnzResults <> UNZ_OK Then
            mUnzResults = NewUnzResults
            Err.Raise &H80045500, TypeName(Me), "Close failed"
        Else
            mUnzResults = UNZ_OK
            unzhFile = UNZ_NULL
            mEndOfFiles = True
        End If
    Else
        'Wasn't open, just quietly return:
        mUnzResults = UNZ_OK
    End If
End Sub
Public Function ListFile(ByRef Name As String, ByRef Crc As Long, ByRef FileSize As Long, Optional NextFile As Boolean) As Boolean
'abcd,xiaoyao
    Dim NewUnzResults As UnzipResults
 
    If unzhFile = UNZ_NULL Then
        mUnzResults = UNZ_NOTOPEN
        Err.Raise &H80045508, TypeName(Me), "Not open"
    End If
    If NextFile Then
        NewUnzResults = unzGoToNextFile(unzhFile)
    Else
        NewUnzResults = unzGoToFirstFile(unzhFile)
    End If
    If NewUnzResults = UNZ_END_OF_LIST_OF_FILE Then
        Name = vbNullString
        mEndOfFiles = True
    ElseIf NewUnzResults = UNZ_OK Then
        mUnzResults = UNZ_OK
        GetCurrentFileInfo Name, Crc, FileSize
        ListFile = True
    Else
        mUnzResults = NewUnzResults
        Err.Raise &H8004550C, TypeName(Me), "FirstFile failed"
    End If
End Function
Public Sub FirstFile(ByRef Name As String, ByRef Crc As Long)
    Dim NewUnzResults As UnzipResults
 
    If unzhFile = UNZ_NULL Then
        mUnzResults = UNZ_NOTOPEN
        Err.Raise &H80045508, TypeName(Me), "Not open"
    End If
 
    NewUnzResults = unzGoToFirstFile(unzhFile)
    If NewUnzResults = UNZ_END_OF_LIST_OF_FILE Then
        Name = vbNullString
        mEndOfFiles = True
    ElseIf NewUnzResults = UNZ_OK Then
        mUnzResults = UNZ_OK
        GetCurrentFileInfo Name, Crc
    Else
        mUnzResults = NewUnzResults
        Err.Raise &H8004550C, TypeName(Me), "FirstFile failed"
    End If
End Sub
 
Public Sub NextFile(ByRef Name As String, ByRef Crc As Long)
    Dim NewUnzResults As UnzipResults
 
    If unzhFile = UNZ_NULL Then
        mUnzResults = UNZ_NOTOPEN
        Err.Raise &H80045510, TypeName(Me), "Not open"
    End If
 
    NewUnzResults = unzGoToNextFile(unzhFile)
    If NewUnzResults = UNZ_END_OF_LIST_OF_FILE Then
        Name = vbNullString
        mEndOfFiles = True
    ElseIf NewUnzResults = UNZ_OK Then
        mUnzResults = UNZ_OK
        GetCurrentFileInfo Name, Crc
    Else
        mUnzResults = NewUnzResults
        Err.Raise &H80045514, TypeName(Me), "NextFile failed"
    End If
End Sub
 
Public Sub OpenZip(ByRef Path As String)
    Dim NewUnzhFile As Long
 
    If unzhFile <> UNZ_NULL Then
        mUnzResults = UNZ_ALREADYOPEN
        Err.Raise &H80045520, TypeName(Me), "Already open"
    End If
 
    NewUnzhFile = unzOpen(Path)
    If NewUnzhFile = UNZ_NULL Then
        mUnzResults = UNZ_OPENFAILED
        Err.Raise &H80045524, TypeName(Me), "Open failed"
    Else
        mUnzResults = UNZ_OK
        unzhFile = NewUnzhFile
    End If
End Sub
 
Private Sub GetCurrentFileInfo(ByRef Name As String, ByRef Crc As Long, Optional ByRef FileSize As Long)
'ABCD,ИЎОДјюРЕПў
    Dim Buffer As String
    Dim unz_file_info As unz_file_info
    Dim NewUnzResults As UnzipResults
    Dim EndPos As Long
 
    Buffer = Space$(MAX_PATH - 1)
    NewUnzResults = unzGetCurrentFileInfo(unzhFile, _
                                          VarPtr(unz_file_info), _
                                          Buffer, _
                                          MAX_PATH, _
                                          WIN32_NULL, _
                                          0, _
                                           vbNullString, _
                                          0)
    If NewUnzResults <> UNZ_OK Then
        mUnzResults = NewUnzResults
        Err.Raise &H80045504, TypeName(Me), "GetCurrentFileInfo failed"
    Else
        FileSize = unz_file_info.uncompressed_size
        EndPos = InStr(Buffer, vbNullChar)
        If EndPos = 0 Then
            Name = Buffer
        Else
            Name = Left$(Buffer, EndPos - 1)
        End If
        Crc = unz_file_info.Crc
    End If
End Sub
 
Private Sub Class_Initialize()
    mEndOfFiles = True
End Sub
 
Private Sub Class_Terminate()
    If unzhFile <> UNZ_NULL Then CloseZip
End Sub
0
Вернулся
 Аватар для HackerVlad
1778 / 673 / 46
Регистрация: 10.09.2021
Сообщений: 2,820
31.10.2024, 17:43
Ну и программку эту я его слегка переделал чтобы картинки загружались автоматически при выборе элемента списка.

Код формы:
Visual Basic
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
Option Explicit
Dim Zip As New MiniZipDir2
 
Private Sub Command1_Click()
Dim SZ
SZ = Split(List1, Chr(9))
Dim Sarr() As String, FileName As String
Sarr = Split(SZ(0), "/")
FileName = Sarr(UBound(Sarr))
Dim Buffer() As Byte
If Zip.ReadFileByte(SZ(0), Buffer()) Then
    Set Picture1.Picture = PictureFromBits(Buffer)
  
    PutToFileBin App.Path & "\" & FileName, Buffer
    'MsgBox "ok"
Else
    MsgBox "err"
End If
End Sub
 
'
'Be sure to set "Break on Unhandled Errors" in the
'Tools|Options... dialog when testing in the IDE!
'
Private Sub Form_Load()
    Dim Crc As Long
    Dim Path As String
With Zip
        .OpenZip App.Path & "\test2.zip"
        '.OpenZip App.Path & "\sample.zip"
'        .FirstFile Path, crc
'        Do While Len(Path)
'            Text1.SelText = LCase$(Right$(String$(7, "0") & Hex$(crc), 8)) _
'                          & " " _
'                          & Path _
'                          & vbNewLine
'            .NextFile Path, crc
'        Loop
    Dim FileSizeArr() As Long, FileList() As String, CrcArr() As Long
    .GetFileList FileList, FileSizeArr, CrcArr
    Dim I As Long
    For I = 0 To UBound(FileList)
        List1.AddItem FileList(I) & Chr(9) & "  Size:" & FileSizeArr(I) & ",crc=" & LCase$(Right$(String$(7, "0") & Hex$(CrcArr(I)), 8))
    Next
      '  .CloseZip
    End With
    If List1.ListCount > 0 Then
        List1.ListIndex = 0
        Command1_Click
    End If
End Sub
 
Function PutToFileBin(FileName As String, bin() As Byte) As Boolean
   '[mycode_id:1940],edittime:2011/7/12 0:04:11
   On Error Resume Next
   Kill FileName
   On Error GoTo Err
       Dim hFile As Integer
       hFile = FreeFile
       Open FileName For Binary As #hFile
       Put #hFile, , bin
       Close #hFile
       PutToFileBin = True
   Exit Function
Err:
       MsgBox Err.Description
End Function
 
Private Sub List1_Click()
    Dim SZ
SZ = Split(List1, Chr(9))
Dim Sarr() As String, FileName As String
Sarr = Split(SZ(0), "/")
FileName = Sarr(UBound(Sarr))
Dim Buffer() As Byte
If Zip.ReadFileByte(SZ(0), Buffer()) Then
    Set Picture1.Picture = PictureFromBits(Buffer)
  
    'PutToFileBin App.Path & "\" & FileName, Buffer
    'MsgBox "ok"
Else
    MsgBox "err"
End If
End Sub
Программа от xiaoyao и HackerVlad
Эта программа использует исключительно API-функции к библиотеке zlibwapi.dll.

Visual Basic
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
Private Declare Function unzOpen Lib "zlibwapi" ( _
    ByVal Path As String) As Long
Private Declare Function unzClose Lib "zlibwapi" ( _
    ByVal unzhFile As Long) As UnzipResults
Private Declare Function unzGoToFirstFile Lib "zlibwapi" ( _
    ByVal unzhFile As Long) As UnzipResults
Private Declare Function unzGoToNextFile Lib "zlibwapi" ( _
    ByVal unzhFile As Long) As UnzipResults
Private Declare Function unzReadCurrentFile Lib "zlibwapi" ( _
    ByVal unzhFile As Long, ByVal BufferPtr As Long, ByVal Size As Long) As UnzipResults
Private Declare Function unzOpenCurrentFile Lib "zlibwapi.dll" (ByVal unzhFile As Long) As Long
Private Declare Function unzCloseCurrentFile Lib "zlibwapi.dll" (ByVal unzhFile As Long) As Long
 
Private Declare Function unzGetCurrentFileInfo Lib "zlibwapi" ( _
    ByVal unzhFile As Long, _
    ByVal pFileInfo As Long, _
    ByVal FileName As String, _
    ByVal FileNameBufferSize As Long, _
    ByVal pExtraField As Long, _
    ByVal ExtraFieldBufferSize As Long, _
    ByVal Comment As String, _
    ByVal CommentBufferSize As Long) As UnzipResults
Миниатюры
Работа с zip архивами  
Вложения
Тип файла: zip MiniZip demo with CRCs (3).zip (269.8 Кб, 2 просмотров)
1
Вернулся
 Аватар для HackerVlad
1778 / 673 / 46
Регистрация: 10.09.2021
Сообщений: 2,820
31.10.2024, 17:49
Цитата Сообщение от testuser2 Посмотреть сообщение
Есть еще вриант с 7zip библой
А этот вариант ты сам уже размусоливай, если ты так хочешь. Но оно тебе надо? Зачем тебе вообще распаковка из ZIP кстати?

Добавлено через 1 минуту
Zlib хотя бы написал Марк Адлер один из авторов основателей ZIP'а

Добавлено через 38 секунд
В свойствах библитеки zlibwapi.dll написано (C) 1995-2013 Jean-loup Gailly & Mark Adler
1
1412 / 876 / 93
Регистрация: 08.02.2017
Сообщений: 3,728
Записей в блоге: 2
31.10.2024, 18:22  [ТС]
Просто плоская функция извлечение файла в байт-массив с поддержкой zip64
Кликните здесь для просмотра всего текста
Visual Basic
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
97
98
99
100
101
102
103
104
105
106
107
Option Explicit
 
Private Const WIN32_NULL As Long = 0
Private Const MAX_PATH As Long = 260
Private Const Z_ERRNO As Long = -1
Private Const UNZ_NULL As Long = 0
Private Enum UnzipResults
    UNZ_OK = 0
    UNZ_END_OF_LIST_OF_FILE = -100
    UNZ_ERRNO = Z_ERRNO
    UNZ_EOF = 0
    UNZ_PARAMERROR = -102
    UNZ_BADZIPFILE = -103
    UNZ_INTERNALERROR = -104
    UNZ_CRCERROR = -105
    UNZ_ALREADYOPEN = -500 'Private extension.
    UNZ_OPENFAILED = -501 'Private extension.
    UNZ_NOTOPEN = -502 'Private extension.
End Enum
Private Type tm_unz
    tm_sec As Long                  'seconds after the minute - [0,59]
    tm_min As Long                  'minutes after the hour - [0,59]
    tm_hour As Long                 'hours since midnight - [0,23]
    tm_mday As Long                 'day of the month - [1,31]
    tm_mon As Long                  'months since January - [0,11]
    tm_year As Long                 'years - [1980..2044]
End Type
Private Type unz_file_info64
    version As Long                 'version made by                 2 bytes
    version_needed As Long          'version needed to extract       2 bytes
    flag As Long                    'general purpose bit flag        2 bytes
    compression_method As Long      'compression method              2 bytes
    dosDate As Long                 'last mod file date in Dos fmt   4 bytes
    crc As Long                     'crc-32                          4 bytes
    compressed_size As Currency     'compressed size                 8 bytes
    uncompressed_size As Currency   'uncompressed size               8 bytes
    size_filename As Long           'filename length                 2 bytes
    size_file_extra As Long         'extra field length              2 bytes
    size_file_comment As Long       'file comment length             2 bytes
    disk_num_start As Long          'disk number start               2 bytes
    internal_fa As Long             'internal file attributes        2 bytes
    external_fa As Long             'external file attributes        4 bytes
    tmu_date As tm_unz
End Type
Private Type unz_global_info
    number_entry As Long
    size_comment As Long
End Type
Private Type unz_global_info64
    number_entry As Currency
    size_comment As Long
End Type
Private Enum CaseSensitivityTypes
    DefoltcaseSensitive& = 0
    CaseSensitive& = 1
    NotCaseSensitive& = 2
End Enum
Private Declare Function unzOpen64 Lib "zlibwapi" (ByVal Path As String) As Long
Private Declare Function unzClose Lib "zlibwapi" (ByVal unzFile As Long) As UnzipResults
Private Declare Function unzGoToFirstFile Lib "zlibwapi" (ByVal unzFile As Long) As UnzipResults
Private Declare Function unzGoToNextFile Lib "zlibwapi" (ByVal unzFile As Long) As UnzipResults
Private Declare Function unzGetGlobalInfo64 Lib "zlibwapi" (ByVal unzFile As Long, UFI As unz_global_info) As UnzipResults
Private Declare Function unzGetCurrentFileInfo64 Lib "zlibwapi" (ByVal unzFile As Long, _
                                                                 ByRef FileInfo As unz_file_info64, _
                                                        Optional ByVal pFileName As Long, _
                                                        Optional ByVal FileNameSize As Long, _
                                                        Optional ByVal pExtraField As Long, _
                                                        Optional ByVal ExtraFieldBufferSize As Long, _
                                                        Optional ByVal Comment As String, _
                                                        Optional ByVal CommentBufferSize As Long) As UnzipResults
Private Declare Function unzOpenCurrentFile Lib "zlibwapi" (ByVal unzFile As Long) As UnzipResults
Private Declare Function unzReadCurrentFile Lib "zlibwapi" (ByVal unzFile As Long, Buffer As Any, ByVal bufferLength As Long) As UnzipResults
Private Declare Function unzCloseCurrentFile Lib "zlibwapi" (ByVal unzFile As Long) As UnzipResults
Private Declare Function unzLocateFile Lib "zlibwapi" (ByVal unzFile As Long, ByVal szFileName As String, Optional ByVal lCaseSensitivity As CaseSensitivityTypes) As UnzipResults 'по умолчанию (когда lCaseSensitivity = 0) поиск не чувствителен регистру
 
Sub testGetFile()
    Dim dt As Date
    Dim ret&, FlPt$, ZipPt$, Buff() As Byte
    FlPt = "D:\tmp\Zip\Diletant\MiniZip demo with CRCs 2019\MiniZip demo\sample.zip"
    ZipPt = "folder2/Rich.rtf"
    
    ret = GetFile(FlPt, ZipPt, Buff())
End Sub
 
Private Function GetFile(FilePath As String, ByVal ZipPath As String, OutBuff() As Byte) As UnzipResults
    Dim unzFile As Long
    Dim UFI As unz_file_info64
    
    If InStr(1, ZipPath, "\") Then ZipPath = Replace(ZipPath, "\", "/")
    
    unzFile = unzOpen64(FilePath)                                   'открываем архив
    If unzFile Then
        GetFile = unzLocateFile(unzFile, ZipPath, NotCaseSensitive) 'ищем файл в архиве
        If GetFile = UNZ_OK Then
            GetFile = unzGetCurrentFileInfo64(unzFile, UFI)         'получаем данные о размере распакованного файла
            GetFile = unzOpenCurrentFile(unzFile)
            With UFI
                .uncompressed_size = .uncompressed_size * 10000     'преобразование currency к целому
                ReDim Preserve OutBuff(.uncompressed_size - 1)
                GetFile = unzReadCurrentFile(unzFile, OutBuff(0), .uncompressed_size) 'распаковываем файл в буфер
            End With
            GetFile = unzCloseCurrentFile(unzFile)
        End If
        GetFile = unzClose(unzFile)
    Else: GetFile = UNZ_NOTOPEN
    End If
End Function


Добавлено через 5 минут
Цитата Сообщение от HackerVlad Посмотреть сообщение
Зачем тебе вообще распаковка из ZIP кстати?
Просто интересно, ну еще чтоб файлы там вордовские, экселевские можно было читать очень быстро

Добавлено через 26 минут
Цитата Сообщение от HackerVlad Посмотреть сообщение
А этот вариант ты сам уже размусоливай, если ты так хочешь.
Есть готовое решение от wqweto VszLib, у него, кстати, там интересный пример файла idl, там есть такая строчка
typedef [public] int INT_PTR; Это очевидно алиас для типа Long. А вот интересно, поддерживается ли в idl настоящий тип INT_PTR ?
1
Модератор
10068 / 3913 / 886
Регистрация: 22.02.2013
Сообщений: 5,863
Записей в блоге: 79
31.10.2024, 18:45
Цитата Сообщение от testuser2 Посмотреть сообщение
Просто интересно, ну еще чтоб файлы там вордовские, экселевские можно было читать очень быстро
Вот я юзал для этих целей как раз код с zipfldr.dll тот что я прикрепил.
Также юзал ее для создания архива, но там есть ньюансы работы.
1
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
inter-admin
Эксперт
29715 / 6470 / 2152
Регистрация: 06.03.2009
Сообщений: 28,500
Блог
31.10.2024, 18:45

access и zip архив
Привет всем! Подскажите... если есть возможность сохранение файла в zip архив Dim FileHeder As String Dim filePath As String ...

Как распаковать ZIP-файл в 7z?
'При помощи VBA WinRAR распаковывает архив в папку … q = Адрес_сохранения_файла 'путь к каталогу, то есть к папке, в конце пути для...

ребята!завтра надо сдать работу,а без этих работ никак((
алгоритмы линейной структуры 1) СОСТАВИТЬ ПРОГРАММУ ВЫЧИСЛЕНИЯ СРЕДНЕГО ЗНАЧЕНИЯ ТРЕХ ВЕЛИЧИН 2) ПОДСЧИТАТЬ И ВЫВЕСТИ НА ЭКРАН СУММУ И...

Замена файла в zip архиве при совпадении имени
Есть несколько excel файлов. например, 1.xls, 2.xls, 3.xls Есть куча zip архивов. например, A (1.xls), B (1.xls,5.doc,3.doc), C (3.xls),...

Как сделать архив zip?
Как сделать архив zip? Какие нужны библиотеки и где их взять? заранее спасибо.


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

Или воспользуйтесь поиском по форуму:
60
Ответ Создать тему
Новые блоги и статьи
Запустил конкурс "тем и промптов для текстовых квестов созданных почти чисто ИИ"
Adler 06.10.2026
Всем привет! За последние три-четыре дня я создал более 16 текстовых квестовых игр используя преимущественно по одному запросу к ИИ на игру. Мне так понравилось смотреть все ветки/ сцены во всех. . .
ИИ не может найти нужный язык в списке
Supersumestria 05.10.2026
Я ему даю вот такое изображение и прошу найти и подчеркнуть немецкий язык. Возвращает он вот это: https:/ / i. **********/ vqBWLe2. png Нужную строчку в 3й колонке просто выдумал. . Это. . .
Новая последняя моя музыка в SUNO
zorxor 05.10.2026
Здравствуйте, дорогие мои друзья! С большой радостью я хотел бы представить вам свою новую последнею музыку, которую сгенерировала мне по моей просьбе нейросеть SUNO. С уважением, zorxor. Это. . .
Программный домашний кинотеатр
russiannick 27.09.2026
Сподобился на программный домашний кинотеатр. В качестве ЯВУ по традиции выбрал js. В помощники взял Яндекс-Алису. Было создано три зала на разные интересы. исторические и ретро сериал Хичкок. . .
Беседа с ИИ о программистах, недопускающих к созданию и правке кода генеративные ИИ и причины этого
zorxor 21.09.2026
Раньше я радовался или получал некоторые эмоции, пусть небольшие, но всё же, от самого процесса написания кода, рекомпиляции и запуска, видя постепенное развитие программы и прочее. А теперь лень. . .
Мобильное приложение ColorStep
pavlinmavlin 17.09.2026
Реализовал приложение Красный, Зеленый, Синий в Unity3d + c#. Название изменил на ColorStep. Приложение прошло модерацию и теперь доступно для скачивания. Делал его сам, шаг за шагом — и вот,. . .
Запрет дублирования строк в табличной части
Maks 13.09.2026
Реализация из решения ниже выполнена на нетиповом справочнике "Нормы ТО" с табличной часть "Виды ТО", разработанного в КА2, со следующими реквизитами: - ВидТО (СправочникСсылка. ВидыТО); - ВидГСМ. . .
Скрипты Tampermonkey для CyberForum, ChatGPT, Claude и пр.
Jin X 06.09.2026
Скрипты Tampermonkey для CyberForum, ChatGPT, Claude и пр. Работая с форумом и нейросетями в браузере часто хочется что-то подкорректировать или добавить какого-то функционала. Ниже прикреплён. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru