merci pour la précision de ta réponse ^^
PureZIP 1.92
je me suis bricolé une fonction pour renommer des fichiers dans une archive au format zip sans décompresser celle ci.
c'est donc très rapide
voila je partage ceci avec vous ça peux être utile
c'est donc très rapide
voila je partage ceci avec vous ça peux être utile
Code : Tout sélectionner
;[zip_rename()]
;par case
;2007
;
;
;
; structures des differents header d'un fichier zip
Structure local_header
version_needed_To_extract.w
general_purpose_bit_flag.w
compression_method.w
last_mod_file_time.w
last_mod_file_date.w
crc_32.l
compressed_size.l
uncompressed_size.l
filename_length.w
extra_field_length.w
EndStructure
Structure central_header
version_made_by.w
version_needed_To_extract.w
general_purpose_bit_flag.w
compression_method.w
last_mod_file_time.w
last_mod_file_date.w
crc_32.l
compressed_size.l
uncompressed_size.l
filename_length.w
extra_field_length.w
file_comment_length.w
disk_number_start.w
internal_file_attributes.w
external_file_attributes.l
relative_offset_of_local_header.l
EndStructure
Structure end_central_header
number_of_this_disk.w
number_of_the_disk_With_the_start_of_the_central_directory.w
total_number_of_entries_in_the_central_dir_on_this_disk.w
total_number_of_entries_in_the_central_dir.w
size_of_the_central_directory.l
offset_of_start_of_central_directory_With_respect_To_the_starting_disk_number.l
zipfile_comment_length.w
EndStructure
;usage zip_rename(zip,ancien nom , nouveau nom)
;
;zip : archive au format zip et chemin d'acces
;ancien nom, fichier dans le zip a renomer
;nouveau nom, nouveau nom du fichier dans le zip a renomer
;
Procedure zip_rename(zip$,src.s,dst.s)
Repeat
b=FindString(zip$,"\",a+1)
If b<>0
a=b
EndIf
Until b=0
filepath$=Left(zip$,a)
file_header_signature$=Space(4)
offsetdiff=Len(dst)-Len(src)
central_size=0
dst_zip=CreateFile(#PB_Any,filepath$+"temp.zip")
src_zip=ReadFile(#PB_Any,zip$)
s1$="PK"+Chr(03)+Chr(04)
s2$="PK"+Chr(01)+Chr(02)
s3$="PK"+Chr(05)+Chr(06)
Repeat
ReadData(src_zip,@file_header_signature$,4)
Select file_header_signature$
Case s1$
local.local_header
ReadData(src_zip,@local,26)
filename.s=Space(local\filename_length)
ReadData(src_zip,@filename,local\filename_length)
datsize=local\extra_field_length+local\compressed_size
*dat=AllocateMemory(datsize)
ReadData(src_zip,*dat,datsize)
If LCase(filename)=LCase(src)
filename=dst
local\filename_length=Len(dst)
EndIf
WriteData(dst_zip,@file_header_signature$,4)
WriteData(dst_zip,@local,26)
WriteData(dst_zip,@filename,local\filename_length)
WriteData(dst_zip,*dat,datsize)
FreeMemory(*dat)
Case s2$
central.central_header
ReadData(src_zip,@central,42)
filename.s=Space(central\filename_length)
ReadData(src_zip,@filename,central\filename_length)
If filename=src
filename=dst
central\filename_length=Len(dst)
found=1
EndIf
central\relative_offset_of_local_header =central\relative_offset_of_local_header+ noffsetdiff
datsize=central\extra_field_length+central\file_comment_length
WriteData(dst_zip,@file_header_signature$,4)
WriteData(dst_zip,@central,42)
WriteData(dst_zip,@filename,central\filename_length)
If datsize>0
*dat=AllocateMemory(datsize)
ReadData(src_zip,*dat,datsize)
WriteData(dst_zip,*dat,datsize)
FreeMemory(*dat)
EndIf
central_size + (46+ central\filename_length+central\extra_field_length+central\file_comment_length)
If found=1
noffsetdiff=offsetdiff
EndIf
Case s3$
endcentral.end_central_header
ReadData(src_zip,@endcentral,18)
endcentral\size_of_the_central_directory=central_size
endcentral\offset_of_start_of_central_directory_With_respect_To_the_starting_disk_number + noffsetdiff
datsize=endcentral\zipfile_comment_length
WriteData(dst_zip,@file_header_signature$,4)
WriteData(dst_zip,@endcentral,18)
If datsize>0
*dat=AllocateMemory(datsize)
ReadData(src_zip,*dat,datsize)
WriteData(dst_zip,*dat,datsize)
EndIf
ext=1
EndSelect
Until Eof(src_zip) Or ext=1
CloseFile(src_zip)
CloseFile(dst_zip)
DeleteFile(zip$)
RenameFile(filepath$+"temp.zip",zip$)
EndProcedure
Intéressant, merci.case a écrit :je me suis bricolé une fonction pour renommer des fichiers dans une archive au format zip sans décompresser celle ci.
Une petite remarque :
Code : Tout sélectionner
Repeat
b=FindString(zip$,"",a+1)
If b<>0
a=b
EndIf
Until b=0
filepath$=Left(zip$,a)Code : Tout sélectionner
filepath$ = GetPathPart(zip$)Et çà serait encore (beaucoup) plus rapide si tu utilisais un algorithme de recherche de type Boyer-Moore pour la recherche de file_header_signature$ au lieu de scanner tout le fichier : http://www.purebasic.fr/english/viewtopic.php?t=27908 et http://www.purebasic.fr/english/viewtopic.php?t=18530
en fait dans tout les cas je suis obligé de lire l'ensemble du fichier puisque si je modifie la taille de la chaine du nom je modifie aussi la taille du fichier donc 'scanner' tout le fichier ne prend pas autant de temps que cela en fait je cree un fichier temporaire que je renomme ensuite une fois la modification faite.
j'ai préféré une approche 'fichier par fichier' a l'intérieur du zip afin de ne pas prendre trop de mémoire. je pourrais aussi charger la totalité du fichier zip en mémoire. modifier le nom avec un décalage de la zone mémoire et re-sauvegarder le tout. et la une fonction de recherche serait peut etre en effet une bonne solution
question , est il possible de n'extraire qu'une partie d'un fichier contenu dans un zip
par exemple je voudrais ne décompresser que les 500 premiers octets d'un fichier par exemple pour lire un header d'un fichier contenu dans l'archive sans decompresser toute l'archive !!
est-ce faisable avec ta lib ? est-ce qu'il me faut aller la modifier,? si oui comment avec quel outils ? la connaissance de l'assembleur est elle requise ...
bon je m'enflamme la
joyeux noel
la je m'en vais reveilloner !
j'ai préféré une approche 'fichier par fichier' a l'intérieur du zip afin de ne pas prendre trop de mémoire. je pourrais aussi charger la totalité du fichier zip en mémoire. modifier le nom avec un décalage de la zone mémoire et re-sauvegarder le tout. et la une fonction de recherche serait peut etre en effet une bonne solution
question , est il possible de n'extraire qu'une partie d'un fichier contenu dans un zip
par exemple je voudrais ne décompresser que les 500 premiers octets d'un fichier par exemple pour lire un header d'un fichier contenu dans l'archive sans decompresser toute l'archive !!
est-ce faisable avec ta lib ? est-ce qu'il me faut aller la modifier,? si oui comment avec quel outils ? la connaissance de l'assembleur est elle requise ...
bon je m'enflamme la
joyeux noel
Avec les fonctions actuelles, non.case a écrit :question , est il possible de n'extraire qu'une partie d'un fichier contenu dans un zip
Ceci dit, si les fichiers ne sont pas trop monstrueux, on peut les décompacter en mémoire avec PureZIP_Archive_ExtractMem(), ce qui est très rapide.
J'utilise cette méthode pour scanner le texte de tous les fichiers d'un ZIP dans mon utilitaire PureTemplate, et c'est vraiment rapide, même sur mon vieux PII-300MHz avec 64Mo de méoire vive ...!
Drag&Drop d'un contenu zip ?
gnozal comment faire si je dois extraire les fichiers de la ListIcon sur le (Bureau) en utilisant le Drag&Drop ?
puis-je extraire les fichiers en mémoire avant et les récupérer avec les fonctions de Drag&Drop ou
je vais chercher encore
Code : Tout sélectionner
Procedure Display_Zip(filename.s)
;à partir du code de Gnozal
ZIP_Handle_Lecture = PureZIP_Archive_Read(filename)
If ZIP_Handle_Lecture
Nb_fichiers = PureZIP_GetFileCount(filename)-1
For i = 0 To Nb_fichiers
PureZIP_GetFileInfo(filename,i , @myFileinfo.PureZIP_FileInfo)
String.s = PeekS(@myFileinfo\filename)
AddGadgetItem(0, -1, String + Chr(10) + myFileinfo\filename)
Next
EndIf
EndProcedure
;
If OpenWindow(0, 0, 0, 440, 494/2, "", #PB_Window_ScreenCentered | #PB_Window_MinimizeGadget | #PB_Window_SystemMenu)
If CreateGadgetList(WindowID(0))
ListIconGadget(0, 10, 10, 420, (494/2)-20, "Name in ZIP [false]", (420/2)-7, #PB_ListIcon_MultiSelect | #PB_ListIcon_FullRowSelect)
AddGadgetColumn(0, 1, "Corrected name [good]", (420 / 2) - 7)
Display_Zip("C:\free.zip")
Repeat
Select WaitWindowEvent()
Case #PB_Event_CloseWindow
Break
EndSelect
ForEver
PureZIP_Archive_Close()
EndIf
EndIfje vais chercher encore
Re: Drag&Drop d'un contenu zip ?
Là tu exagères je trouve ... avec un rappel dans le forum anglais même pas un jour après ce post !SpaceMan a écrit :gnozal comment faire si je dois extraire les fichiers de la ListIcon sur le (Bureau) en utilisant le Drag&Drop ?
Je veux bien passer du temps sur des problèmes liés à PureZIP mais c'est une question de programmation générale (Drag&Drop).
Je n'ai pas le temps d'approfondir la question, désolé.