PureBasic

Forums PureBasic
Nous sommes le Sam 19/Oct/2019 13:15

Heures au format UTC + 1 heure




Poster un nouveau sujet Répondre au sujet  [ 9 messages ] 
Auteur Message
 Sujet du message: J'utilise un map avec structure, comment faire recherche ?
MessagePosté: Sam 14/Juil/2018 22:45 
Hors ligne
Avatar de l’utilisateur

Inscription: Lun 24/Sep/2012 20:57
Messages: 46
Localisation: Somme
Bonjour ami(e)s codeur !

voici mon bout de code pour imager mon problème :

Code:
;Projet Administratif
;on indique au logiciel quelle repertoire surveillé, il vérifie et detecte tous dossiers/fichier créer :
;-1 il vérifie si des fichier précédement indexé ne s'y trouvent plus (alors efface de l'index)
;-2 si l'heure des fichiers, et leurs taille à changer, il met à jour l'index
;-3 si un fichier si trouve, mais n'est pas indexer, alors il vérifie que ce soit pas un doublon : si oui efface : si non ajoute à l'index

;-4fait un check du dossier surveillé via un "tree" ou voir pour routine kernel ?
;-5 : Pourquoi pas une option sync vers (ftp/dossier) /backup / zip ?


;Ce mode de check permet de façon optimale d'avoir une méthode fiable de trie de mes dossiers administratif !
;car l'utilisateur à juste à créer des sous dossier par rubriques (Assurances\EDF...) puis à ajouter les fichiers au bon emplacement depuis l'explorateur.
;si il y a des doublons (un même fichier mais nommé différemment) il notifie l'utilisateur qui peut décider celui a effacer.

;-----------------------------------
Structure fichier_interne
  emplacement_fichier.s     ;-emplacement et nom du fichier (chemin relatif à la racine a mettre en place plus tard, pour l'instant complet).
  date_creation.s           ;prise via routine filesysteme
  taille.l                  ;Taille du fichier
EndStructure

;-variable globale
Global NewMap systemfile.fichier_interne() ;clef de reference=hash de chaque fichier indexer
Global racine.s                    ;dossier racine à surveiller
Global file_index.s="index.dat"           ;nom fichier d'index
Global version.l=1
Global titre.s="Administratif - AntiDoublon"
Global quit.l                             ;arrête les thread et le programme lorsqu'a + 0
Global thread_error.l                     ;permetra de notifier des erreurs d'enregistrement de l'index
emplacement_user_param.s=GetUserDirectory(#PB_Directory_ProgramData)+"Administratif\AntiDoublon\param.ini";emplacement des parametres de l'utilisateur
If FileSize(GetUserDirectory(#PB_Directory_ProgramData)+"Administratif")=-1:CreateDirectory(GetUserDirectory(#PB_Directory_ProgramData)+"Administratif\"):EndIf

If FileSize(GetUserDirectory(#PB_Directory_ProgramData)+"Administratiff\AntiDoublon")=-1:CreateDirectory(GetUserDirectory(#PB_Directory_ProgramData)+"Administratif\AntiDoublon"):EndIf

Procedure read_disk_index();procedure qui va lire le fichier index et charger en mémoire l'index map
  ;et va aussi faire un check des fichier par la même occasion
Debug "Lecture du fichier disk index"
Protected id_f.l,hash.s,ligne.s
id_f.l=OpenFile(#PB_Any,racine+file_index,#PB_Ascii)
If id_f.l;si fichier index ouvert
  While Eof(id_f.l)=0
    ligne.s=ReadString(id_f.l,#PB_Ascii)
    hash.s=StringField(ligne.s,1,",")
    systemfile(hash.s)\date_creation=StringField(ligne.s,2,",")
    systemfile(hash.s)\emplacement_fichier=StringField(ligne.s,3,",")
    systemfile(hash.s)\taille.l=Val(StringField(ligne.s,4,","))
    If FileSize(StringField(ligne.s,3,","))<0:DeleteMapElement(systemfile(),hash):EndIf
  Wend
CloseFile(id_f):ProcedureReturn MapSize(systemfile())
Else;fichier index erreur d'ouverture
ProcedureReturn 0
EndIf
EndProcedure

Procedure thread_update_index(n.l);thread qui régulièrement met à jour le fichier d'index (vérifie toutes les 10 secondes si la mapsize a changer)
Debug "Lancement du thread update disk index" 
Protected id_f.l,hash.s,ligne.s,lastmapsize.l
Shared thread_error.l;-permet de notifier l'utilisateur lors d'erreur de sauvegarde de l'index !
lastmapsize.l=0
Repeat
If MapSize(systemfile())<>lastmapsize.l
id_f.l=CreateFile(#PB_Any,racine.s+file_index,#PB_Ascii)
If id_f
ForEach systemfile()
hash.s=MapKey(systemfile())
ligne.s=hash.s+","+systemfile(hash.s)\date_creation+","+systemfile(hash.s)\emplacement_fichier+","+Str(systemfile(hash.s)\taille)
WriteStringN(id_f.l,ligne.s,#PB_Ascii)
Next
CloseFile(id_f)
Debug "index disque mis à jour."
thread_error.l=0
lastmapsize.l=MapSize(systemfile())
Else;erreur ouverture fichier d'index
thread_error.l=1:Delay(2200):Debug "erreur ouverture disk index, essais dans 2 secondes..."
EndIf
Else
Delay(5000):Debug "Attente mise à jour de l'index mémoire."
EndIf
Until quit.l=1
Debug "fin du thread update index"
EndProcedure

Procedure.s Scan_Directory(source.s,type=0,rek=0) ; Source="repertoire",type 0=fichier 1=dossier 2=dossier et fichier, indice
;total.s = scan_Directory(PathRequester("test",""))
;position=2
Protected s_name.s,s_type.l,s_fullname.s,sortie.s
If Right(source, 1) <> "\" : source + "\" : EndIf
If ExamineDirectory(rek, source, "*.*")
While NextDirectoryEntry(rek)
s_name.s = DirectoryEntryName(rek) : s_type = DirectoryEntryType(rek)
Select s_type
Case #PB_DirectoryEntry_File
If type=0 Or type=2
s_fullname.s = source + s_name
sortie.s + s_fullname.s+Chr(13)
EndIf
Case #PB_DirectoryEntry_Directory
If s_name <> "." And s_name <> ".."
If type=1 Or type=2
sortie.s + source+s_name+Chr(13)
EndIf
sortie.s + Scan_Directory(source + s_name,type, rek + 1)
EndIf
EndSelect
Wend
FinishDirectory(rek)
ProcedureReturn sortie.s
EndIf
EndProcedure

Procedure thread_check_racine(n.l);(pas encore utilisé) verifie les fichiers dans racine
  Debug "lancement du thread check racine"
Protected fichier.s,fichiers.s,a.l,hash.s
Repeat
fichiers.s=scan_Directory(racine,0)
For a=1 To CountString(fichiers.s,Chr(13))
fichier.s=StringField(fichiers.s,a,Chr(13))
If fichier<>racine+file_index;ignore le fichier d'index en lui même
hash.s=FileFingerprint(fichier.s,#PB_Cipher_SHA2,256)
systemfile(hash)\emplacement_fichier=fichier.s
systemfile(hash)\date_creation=FormatDate("%dd/%mm/%yyyy %hh:%ii:%ss",GetFileDate(fichier.s,#PB_Date_Modified))
systemfile(hash)\taille=FileSize(fichier.s)
EndIf
Next a
Debug "Nombre de fichier scanné : "+Str(CountString(fichiers.s,Chr(13)))
Until quit.l=1
Debug "Fin du thread check racine"
EndProcedure

UseSHA2Fingerprint()

If FileSize(emplacement_user_param)<0;fichier de param inexistant
  MessageRequester(titre.s,"Configuration du logiciel au premier lancement,"+#CRLF$+"Veuillez indiquez le dossier à surveiller.",#PB_MessageRequester_Ok)
  racine.s=PathRequester("Dossier à surveiller : ",GetUserDirectory(#PB_Directory_Documents))
  If racine.s
    OpenFile(0,emplacement_user_param)
    WriteStringN(0,racine.s)
    CloseFile(0);a sauvegarder le chemin racine a surveiller
  Else
   End
  EndIf
Else;paramétrage déjà fait
  OpenFile(0,emplacement_user_param)
  racine.s=ReadString(0,#PB_Ascii)
  CloseFile(0);a sauvegarder le chemin racine a surveiller
EndIf

If FileSize(racine.s+file_index.s)>0
Debug "index chargé, nombre de fichier : "+Str(read_disk_index());si fichier d'index déjà existant : alors le charge
CreateThread(@thread_update_index(),0)
Else             ;si non scandirectory et indexation
CreateThread(@thread_update_index(),0)
Debug "Scan de premier lancement"
fichiers.s = scan_Directory(racine,0)
For a=1 To CountString(fichiers.s,Chr(13))
fichier.s=StringField(fichiers.s,a,Chr(13))
If fichier.s<>racine+file_index
hash.s=FileFingerprint(fichier.s,#PB_Cipher_SHA2,256)
systemfile(hash)\emplacement_fichier=fichier.s
systemfile(hash)\date_creation=FormatDate("%dd/%mm/%yyyy %hh:%ii:%ss",GetFileDate(fichier.s,#PB_Date_Modified))
systemfile(hash)\taille=FileSize(fichier.s)
EndIf
Next a
Debug "Nombre de fichier scanné : "+Str(CountString(fichiers.s,Chr(13)))
EndIf

;-maintenant boucle principal qui gere l'affichage des notifications
;test de recherche dans la map :
For a=1 To 10:Delay(1000):Next a
quit.l=1
For a=1 To 10:Delay(1000):Next a

If FindMapElement(systemfile(),"11a62cf53b1fdf8972c048e8fe3d6c5af9208f17717094904cc9874664dc691a"):Debug "hash trouvé":EndIf
If FindMapElement(systemfile.fichier_interne(),"20/06/2018 00:19:53"):Debug "date trouvé":EndIf
If FindMapElement(systemfile.fichier_interne(),"70984"):Debug "taille trouvé":EndIf
End


Vous l'aurez compris je cherche à créer un logiciel qui surveille un dossier racine et tous ce qui ce qui est créer modifier ou supprimé est indexer, modifier ou supprimé de l'index.

le but de ce programme est administratif (j'ai 600 go de fichiers à nettoyer sur mon nas, et les logiciels anti doublon existant ne me conviennent pas, donc l'idée : je me tappe la visualisation de mes fichier et les déplace dans des sous dossiers correspondant (assurance..) qui se trouve dans le nouveau répertoire surveiller "racine", donc si le fichier existe déjà mon programme m'affiche une notif et me laisse choisir quelle fichier conserver.

Vous comprenez je pense mon problème : je souhaite vérifier dans ma map structuré, chercher par nom de fichier/ date/ emplacement, snas pour autant faire un filefingerprint systématique pour avoir le hash...

Quelqu'un peut m'aider svp ?
Par avance merci !!


Haut
 Profil  
Répondre en citant le message  
 Sujet du message: Re: J'utilise un map avec structure, comment faire recherche
MessagePosté: Dim 15/Juil/2018 0:08 
Hors ligne
Avatar de l’utilisateur

Inscription: Sam 31/Juil/2004 22:32
Messages: 1140
Il faut utiliser une base de données. Ça sera plus pratique, plus rapide et moins consommant en mémoire. PB embarque sqlite qui est absolument idéal dans ce genre de situation et très simple à utiliser (falsam a balancé plein de tuto dans la section débutant).


Haut
 Profil  
Répondre en citant le message  
 Sujet du message: Re: J'utilise un map avec structure, comment faire recherche
MessagePosté: Dim 15/Juil/2018 1:14 
Hors ligne
Avatar de l’utilisateur

Inscription: Lun 24/Sep/2012 20:57
Messages: 46
Localisation: Somme
Merci, je vais allé regarder les tutos.


Haut
 Profil  
Répondre en citant le message  
 Sujet du message: Re: J'utilise un map avec structure, comment faire recherche
MessagePosté: Dim 15/Juil/2018 7:45 
Hors ligne

Inscription: Sam 08/Fév/2014 15:19
Messages: 1616
Alternative possible pour synchroniser rapidement des fichiers (Windows) utiliser l'attribut archive.

Cet attribut, positionné automatiquement par l'OS, est mis sur tout nouveau fichier et remis dès qu'un fichier / répertoire est modifié.
Il est géré par PB
Il est aussi utilisable avec des commandes comme Xcopy.
On peut copier déplacer des fichiers et indiquer s'il faut garder ou réinitialiser l'attribut.

Si la sauvegarde est sur un NAS avec un filesystem un*x l'attribut archive n'existe pas, mais on peut indiquer à Samba d'utiliser l'attribut +x (inutile en dos) avec une option dans le smb.conf (map archive = yes)

:wink:

_________________
Windows 10 Famille x64 + Linux (Slackware, Debian sur Oracle VirtualBox 6.0)


Haut
 Profil  
Répondre en citant le message  
 Sujet du message: [Résolu partiellement] logiciel anti doublon (en console)
MessagePosté: Dim 15/Juil/2018 12:30 
Hors ligne
Avatar de l’utilisateur

Inscription: Lun 24/Sep/2012 20:57
Messages: 46
Localisation: Somme
Voiçi mon code pour faire déjà le gros de mon boulot detrie, si cela peut servire à quelqu'un :
Code:
;Projet Anti-Doublon
;on indique au logiciel quelle repertoire surveillé, il vérifie et detecte tous dossiers/fichier créer :
;-1 scandirectory nous donne la liste des fichiers, leurs emplacements, et le total de fichier
;-2 lance un thread qui va scanner les fichiers un par un et tenir une map systemfile(HASH.s)=Emplacement du fichier
;-2b via une variable (global/shared) compteur_scan.l (qui servira dans la boucle for/next indique le nombre de fichier déjà scanner/traiter
;-2c dans cette boucle si le hash du fichier scanner est déjà utiliser dans la map = doublon alors on efface, sinon on ajoute a la map
;-2d on incrémente un (global/shared) compteur_delete.l qui undique le nombre de fichiers supprimé car doublon.
;-3 le programme principale sert uniquement à l'affichage de la progression, et du nombre de fichiers supprimé
;-4 une variable Global QUIT.L permet de fermer proprement le thread
;------------------

;-variable globale
Global NewMap systemfile.s();clef de reference=hash de chaque fichier indexer
Global titre.s="Anti-Doublon"
Global racine.s;emplacement racine à scanné
Global quit.l                             ;arrête les thread et le programme
Global compteur_scan.l
Global compteur_delete.l
Global fichiers.s;listes des fichiers généré par scandirectory

Procedure.s Scan_Directory(source.s,type=0,rek=0) ; Source="repertoire",type 0=fichier 1=dossier 2=dossier et fichier, indice
;total.s = scan_Directory(PathRequester("test",""))
;position=2
Protected s_name.s,s_type.l,s_fullname.s,sortie.s
If Right(source, 1) <> "\" : source + "\" : EndIf
If ExamineDirectory(rek, source, "*.*")
While NextDirectoryEntry(rek) And quit.l=0
s_name.s = DirectoryEntryName(rek) : s_type = DirectoryEntryType(rek)
Select s_type
Case #PB_DirectoryEntry_File
If type=0 Or type=2
s_fullname.s = source + s_name
sortie.s + s_fullname.s+Chr(13)
EndIf
Case #PB_DirectoryEntry_Directory
If s_name <> "." And s_name <> ".."
If type=1 Or type=2
sortie.s + source+s_name+Chr(13)
EndIf
sortie.s + Scan_Directory(source + s_name,type, rek + 1)
EndIf
EndSelect
Wend
FinishDirectory(rek)
Debug "fin du (sous)scan "+Str(rek)
ProcedureReturn sortie.s
EndIf
EndProcedure

Procedure thread_filefingermap(n.l);verifie les fichiers dans racine
Protected fichier.s,hash.s
Shared compteur_scan.l,compteur_delete.l
For compteur_scan=1 To CountString(fichiers.s,Chr(13))
fichier.s=StringField(fichiers.s,compteur_scan,Chr(13))
If fichier
hash.s=FileFingerprint(fichier.s,#PB_Cipher_SHA2,256)

If systemfile(hash.s)<>""; si il y a déjà un fichier identitique...
  DeleteFile(fichier.s,#PB_FileSystem_Force)
  compteur_delete+1
Else; sinon on ajoute a la map
  systemfile(hash)=fichier.s
EndIf

EndIf
If quit.l=1:Break:EndIf
Next compteur_scan
Debug "fin du thread fingerprintmap"
EndProcedure

UseSHA2Fingerprint()
racine.s=PathRequester(titre,GetUserDirectory(#PB_Directory_Desktop))
If racine
fichiers.s=scan_Directory(racine,0):total_fichier.l=CountString(fichiers.s,Chr(13))
OpenConsole(titre+" "+Str(total_fichier)+" a scanner.")
th=CreateThread(@thread_filefingermap(),0)
Repeat
  Delay(1000)
  ConsoleTitle(titre+" "+Str(total_fichier-compteur_scan)+" restant a scanner.")
  If compteur_delete>0 And lastdelete<>compteur_delete
    PrintN(Str(compteur_delete)+" fichiers supprimé.")
    lastdelete=compteur_delete;permet d'éviter l'affichage d'une meme info..
  EndIf
Until total_fichier=compteur_scan Or IsThread(th)=0
Delay(5000)
CloseConsole()
EndIf
End


Merci pour vos réponses, mais le sqlite me parait compliqué (je suis un peut rebuté).


Haut
 Profil  
Répondre en citant le message  
 Sujet du message: Re: J'utilise un map avec structure, comment faire recherche
MessagePosté: Dim 15/Juil/2018 16:33 
Hors ligne
Avatar de l’utilisateur

Inscription: Sam 23/Sep/2006 18:32
Messages: 6658
Localisation: Isere
J'ai testé ça m'a bien éffacé un doublon de film que j'avais créé :D
Heureusement au passage que la copie avait pas foiré :lol:
Merci du partage 8)

_________________
ImageLe bonheur est une route...
Pas une destination

PureBasic Forum Officiel - Site PureBasic


Haut
 Profil  
Répondre en citant le message  
 Sujet du message: Re: [Résolu partiellement] logiciel anti doublon (en console
MessagePosté: Dim 15/Juil/2018 17:28 
Hors ligne
Avatar de l’utilisateur

Inscription: Sam 31/Juil/2004 22:32
Messages: 1140
caussatjerome a écrit:
Merci pour vos réponses, mais le sqlite me parait compliqué (je suis un peut rebuté).

Malheureusement, y'a pas vraiment d'autre solution : une map, c'est fait pour chercher dans sa hashtable, ça va pas être capable de chercher dans les champs d'une structure.
Tu peux toujours faire une grosse loop foreach sur l'ensemble des éléments de ta map mais c'est va vite devenir lent et consommer beaucoup de ressources pour rien...


Haut
 Profil  
Répondre en citant le message  
 Sujet du message: Re: J'utilise un map avec structure, comment faire recherche
MessagePosté: Lun 16/Juil/2018 19:17 
Hors ligne
Avatar de l’utilisateur

Inscription: Lun 24/Sep/2012 20:57
Messages: 46
Localisation: Somme
Oui en effet, j'y ai pensé raison pour laquelle je cherchait une autre solution, le petit programme que j'ai créer simplement pour faire un index de shafingerprint et emplacements et suppression de doublon, me suffit pour l'instant car cela va me permettre d'effacer les fichier en double/triple/quadruple exemplaire sur mes disques :mrgreen:

Mais à la longue je verrais pour faire quelque chose de plus sympa :D


Haut
 Profil  
Répondre en citant le message  
 Sujet du message: Re: J'utilise un map avec structure, comment faire recherche
MessagePosté: Lun 16/Juil/2018 20:50 
Hors ligne
Avatar de l’utilisateur

Inscription: Sam 31/Juil/2004 22:32
Messages: 1140
Je t'encourage vraiment à essayer un peu plus SQLite. Pour commencer, tu peux utiliser un outil graphique pour construire ta base de donnée : ça t'évitera d'avoir à la créer directement en SQL; perso j'utilise DB Browser for SQLite.
Pour le reste, tu n'as que deux fonctions SQL à apprendre pour débuter : INSERT et SELECT. SQL est une techno standard, donc si les tutos que tu trouves ici ne te plaisent pas, tu peux consulter n'importe quelle autre source d'information sur internet; ça marchera avec PB.


Haut
 Profil  
Répondre en citant le message  
Afficher les messages postés depuis:  Trier par  
Poster un nouveau sujet Répondre au sujet  [ 9 messages ] 

Heures au format UTC + 1 heure


Qui est en ligne

Utilisateurs parcourant ce forum: Aucun utilisateur enregistré et 0 invités


Vous ne pouvez pas poster de nouveaux sujets
Vous ne pouvez pas répondre aux sujets
Vous ne pouvez pas éditer vos messages
Vous ne pouvez pas supprimer vos messages

Rechercher:
Aller à:  
cron

 


Powered by phpBB © 2008 phpBB Group | Traduction par: phpBB-fr.com
subSilver+ theme by Canver Software, sponsor Sanal Modifiye