Code : Tout sélectionner
#DEBUG_ZIP_FILE_INFO = 0
#ZIP_CENTRAL_FILE_HEADER_SIGNATURE = $02014b50
#ZIP_ERROR_FILE_DOES_NOT_EXIST = -1
#ZIP_ERROR_NO_CENTRAL_FILE_HEADER_SIGNATURE_FOUND = -2
Structure ZIP_file_info
offset_CENTRAL_FILE_HEADER_SIGNATURE.l
version_made_by.u
version_needed_to_extract.u
general_purpose_bit_flag.u
compression_method.u
last_mod_file_time.u
last_mod_file_date.u
crc_32.l
compressed_size.q ; 4 byte in the zip file
uncompressed_size.q ; 4 byte in the zip file
file_name_lenght.u
extra_field_lenght.u
file_comment_lenght.u
disk_number_start.u
internal_file_attributes.u
external_file_attributes.q ; 4 byte in the zip file
relative_offset_of_local_header.q ; 4 byte in the zip file
file_name.s
extra_field.s ; en string pour le moment
file_comment.s
EndStructure
Structure ZIP_info
zip_total_size.q
List File.ZIP_file_info()
EndStructure
Procedure Zip_INFO(file.s, *zip_info.ZIP_info)
; Overall .ZIP file format:
;
; [local file header 1]
; [file Data 1]
; [Data descriptor 1]
; .
; .
; .
; [local file header n]
; [file Data n]
; [Data descriptor n]
; [archive decryption header]
; [archive extra Data record]
; [central directory]
; [zip64 End of central directory record]
; [zip64 End of central directory locator]
; [End of central directory record]
hd_file = ReadFile(#PB_Any, file)
If hd_file = 0 : ProcedureReturn #ZIP_ERROR_FILE_DOES_NOT_EXIST : EndIf
InitializeStructure(*zip_info, ZIP_info)
; on stock la taille du fichier (ca peut servir)
*zip_info\zip_total_size = Lof(hd_file)
; on scan pour trouver le #ZIP_CENTRAL_FILE_HEADER_SIGNATURE qui est le début du listage des fichiers d'un zip
While Eof(hd_file) = 0
If ReadLong(hd_file) = #ZIP_CENTRAL_FILE_HEADER_SIGNATURE
AddElement(*zip_info\File())
;{ add new file informations
With *zip_info\File()
\offset_CENTRAL_FILE_HEADER_SIGNATURE = Loc(hd_file) - 4
\version_made_by = ReadUnicodeCharacter(hd_file)
\version_needed_to_extract = ReadUnicodeCharacter(hd_file)
\general_purpose_bit_flag = ReadUnicodeCharacter(hd_file)
\compression_method = ReadUnicodeCharacter(hd_file)
\last_mod_file_time = ReadUnicodeCharacter(hd_file)
\last_mod_file_date = ReadUnicodeCharacter(hd_file)
ReadData(hd_file, *zip_info\File() + OffsetOf(ZIP_file_info\crc_32), 4)
ReadData(hd_file, *zip_info\File() + OffsetOf(ZIP_file_info\compressed_size), 4)
ReadData(hd_file, *zip_info\File() + OffsetOf(ZIP_file_info\uncompressed_size), 4)
\file_name_lenght = ReadUnicodeCharacter(hd_file)
\extra_field_lenght = ReadUnicodeCharacter(hd_file)
\file_comment_lenght = ReadUnicodeCharacter(hd_file)
\disk_number_start = ReadUnicodeCharacter(hd_file)
\internal_file_attributes = ReadUnicodeCharacter(hd_file)
ReadData(hd_file, *zip_info\File() + OffsetOf(ZIP_file_info\external_file_attributes), 4)
ReadData(hd_file, *zip_info\File() + OffsetOf(ZIP_file_info\relative_offset_of_local_header), 4)
\file_name = Space(\file_name_lenght)
ReadData(hd_file, @*zip_info\File()\file_name, \file_name_lenght)
\extra_field = Space(\extra_field_lenght)
ReadData(hd_file, @*zip_info\File()\extra_field, \extra_field_lenght)
\file_comment = Space(\file_comment_lenght)
ReadData(hd_file, @*zip_info\File()\file_comment, \file_comment_lenght)
CompilerIf #DEBUG_ZIP_FILE_INFO
Debug ""
Debug "Zip_Info : NEW FILE FOUND : " + Str(\offset_CENTRAL_FILE_HEADER_SIGNATURE)
Debug " version made by : " + Str(\version_made_by)
Debug " version needed To extract : " + Str(\version_needed_to_extract)
Debug " general purpose bit flag : " + Bin(\general_purpose_bit_flag)
Debug " compression method : " + Str(\compression_method)
Debug " last mod file time : " + Str(\last_mod_file_time)
Debug " last mod file date : " + Str(\last_mod_file_date)
Debug " crc-32 : " + Str(\crc_32)
Debug " compressed size : " + Str(\compressed_size)
Debug " uncompressed size : " + Str(\uncompressed_size)
Debug " file name length : " + Str(\file_name_lenght)
Debug " extra field length : " + Str(\extra_field_lenght)
Debug " file comment length : " + Str(\file_comment_lenght)
Debug " disk number start : " + Str(\disk_number_start)
Debug " internal file attributes : " + Str(\internal_file_attributes)
Debug " external file attributes : " + Str(\external_file_attributes)
Debug " relative offset of local header : " + Str(\relative_offset_of_local_header)
Debug ""
Debug " file name (variable size) : " + \file_name
Debug " extra field (variable size) : " + \extra_field
Debug " file comment (variable size) : " + \file_comment
Debug ""
CompilerEndIf
EndWith
;}
ElseIf ListSize(*zip_info\File()) And Eof(hd_file) = 0
FileSeek(hd_file, Loc(hd_file) - 2) ; on parcours tout les 2 bits
EndIf
Wend
If ListSize(*zip_info\File()) = 0
CompilerIf #DEBUG_ZIP_FILE_INFO
Debug "ZIP_info : Erreur : no CENTRAL_FILE_HEADER_SIGNATURE find"
CompilerEndIf
ProcedureReturn #ZIP_ERROR_NO_CENTRAL_FILE_HEADER_SIGNATURE_FOUND
EndIf
CloseFile(hd_file)
EndProcedure
;{ TEST ZONE
test = 0
Select test
Case 0
FILETEST$ = "exemple\001.zip"
Case 1
FILETEST$ = "exemple\test_text.zip"
EndSelect
Define filetest.ZIP_info
Zip_INFO(FILETEST$, filetest)
; on affiche tout la liste des fichiers de l'archive
ForEach filetest\File()
Debug filetest\File()\file_name
Next
;}
End
Je me demande si qqun à pas fait une librairie de lecture d'archive un peu comme la dll de 7zip.
Fred devrais y penser, même si ça prendrais quelques temps à implémenter et à maintenir à jour, l'intéret apporté par une telle lib pour des applis commerciales !!
Il faudrait pouvoir charger le fichjier, décompresser chaque fichier en mémoire et choisir de l'écrire sur le disque ou pas.
Je n'ai pas le courage de traduire les wrappers en C#, C, C++, .Net, etc .. de 7z.dll -_- , c'est possible à mon avis, mais il a y de code que je comprend pas, ou mal documenté.