Page 1 sur 1

Sauvegarde automatique de fichiers

Publié : lun. 04/janv./2016 11:36
par Micoute
Bonjour à tous,

j'aimerais me faire un logiciel de sauvegarde automatique de fichiers et je ne sais pas par où commencer.

Il faudrait que le programme compare le nom et la taille du ou des programmes et si le nom est identique et que la taille diffère d'un certain nombre d'octets à définir ou déjà défini, alors la sauvegarde automatique ferait son taf.

En fait, je pense que ce serait un programme qui travaille en tâche de fond, tel qu'un antivirus, par exemple.

En n'oubliant pas de vous remercier pour vos idées qui j'en suis sûr me seront d'un grand secours.

Re: Sauvegarde automatique de fichiers

Publié : lun. 04/janv./2016 13:12
par Ar-S
Je te souhaite bon courage, c'est très chiant ce genre de soft, perso je passe par un simple fichier batch qui permet de faire de la sauvegarde incrémentielle. C'est moche mais ça marche bien !

Re: Sauvegarde automatique de fichiers

Publié : lun. 04/janv./2016 13:56
par Marc56
Bonjour Micoute,

Ce type d'outils existe déjà (RoboCopy, SyncBackup etc), mais c'est aussi un exercice intéressant à faire soi-même.

Tout ce dont tu as besoin est dans la bibliothèque FileSystem

Plusieurs méthodes:
  • Utiliser l'attribut archive (positionné par le système (Windows et Linux/Samba)) sur tout fichier nouveau ou modifié.
  • Comparer par date avec DirectoryEntryDate() sans oublier qu'il faut se baser sur la date de modification (#PB_Date_Modified) et non pas sur la date de création.
Simple à faire, si tu ne surveilles qu'un seul répertoire, un peu plus complexe s'il y a aussi des sous-répertoires.

Dans l'absolu:
- Tant qu'il y a des fichiers dans le répertoire source
- Vérifier s'il existe dans la destination
- Si non: copier
- Si oui: comparer la date de modification (source plus neuf ? copier)

S'il y a beaucoup de fichier, alors on peut maintenir des listes en mémoire, mais ça devient plus compliqué.

Pour faire du monitoring, il suffit que le programme scanne le(s) répertoire(s) toutes les x secondes.

Amélioration possible: conserver plusieurs copies du même fichier en mettant un timestamp dans le nom du fichier copié.

J'en avait fait un il y a deux ans, je vais le remettre à jour dès que j'ai le temps.

Ça c'est ma méthode de sauvegarde par duplication d'arborescence.

L'autre consiste à faire une archive des différentes versions, pour cela, même méthode, mais au lieu du répertoire de destination, je fais une archive (.zip ou .7z) soit avec les fonctions internes de PB soit en invoquant 7z.exe ou 7zG.exe s'il y a beaucoup de fichiers.

:wink:

Re: Sauvegarde automatique de fichiers

Publié : lun. 04/janv./2016 15:02
par falsam
Spock a écrit :mieux vaut faire une comparaison de la Date !! pas de la taille
Tout à fait d'accord avec Spock (Pour une fois que je suis d'accord avec lui ^^")
Marc56 a écrit :Pour faire du monitoring, il suffit que le programme scanne le(s) répertoire(s) toutes les x secondes.
Are you crazy ? :mrgreen:

Ce que j'aurais fait:

1 - Un code en systray qui permet de lancer à la demande ou en différé la sauvegarde des fichiers.
2 - La date time de la dernière sauvegarde est mémoriser dans un fichier texte par exemple.
2 - Les dossiers à scanner se trouve dans un fichier JSON.
3 - Pour chacun des dossiers, une boucle récursive analysant chaque fichier de ces dossiers et teste si la date de modification ou de création du fichier est supérieur à celle de la dernière sauvegarde : Si oui, mémorisation du nom du fichier dans une liste de sauvegarde.
4 - Les dossiers sont tous analysés : Lancement de la sauvegarde.

Pour chacun de ces points, les codes existent sur le forum.

Re: Sauvegarde automatique de fichiers

Publié : lun. 04/janv./2016 16:28
par Micoute
Merci beaucoup pour vos réponses.

La comparaison de la date, c'est noté, le code en systray, d'accord, la dernière sauvegarde dans un fichier JSON, très bien, sauvegarde après analyse, ok aussi.

Quel joli travail en perspective, mais tout à fait à ma portée.

Merci encore.

Re: Sauvegarde automatique de fichiers

Publié : lun. 04/janv./2016 17:40
par Marc56
Voila de quoi d'amuser :)

Ce petit programme créé un .Zip nommé Zip_<nomDuDossier>_YYYYMMDD-HHMMSS.zip dans le dossier où il a été lancé avec le contenu du dossier qui lui a été glissé (par drag'n'drop)

Il ne s'occupe pas des dates, il sert juste à avoir des dossiers projets complets zippés à des dates différentes, sans s'occuper de gérer soi-même cet horodatage dans le nom du fichier. (pas de risque d'erreur)

Code : Tout sélectionner

; Sauvegarde Dossier vers un .Zip horodaté
; Créé une archive Zip datée avec un dossier reçu par D&D
; (C)Marc56 - 04/01/16
;
; Utilisation
; 1. Compiler ce programme
; 2. Le copier dans le dossier d'archive
; 3. Créer un raccourci sur le bureau
; 4. Faire un drag'n'drop du dossier à archiver sur l'icône
; 5. Le .Zip se trouve dans le dossier d'archive avec le nom Zip_<répertoire>_YYYYMMDD_HHMMSS.zip

EnableExplicit

Enumeration 
    #Rep
    #Zip
EndEnumeration

; -- Le programme doit recevoir un dossier à archiver par D&D
If Not CountProgramParameters()
    MessageRequester("Pas de Dossier à Archiver", 
                     "Aucun paramètre n'a été transmis" + Chr(10) + 
                     "Faites glisser un dossier sur l'icône du programme.", 48)
    End
EndIf

; -- Le nom du dossier reçu par D&D
Global Folder_Name.s = ProgramParameter(0)

; -- Nom de l'archive générée
Global Archive_Name.s = "Zip_" + 
                        StringField(Folder_Name, CountString(Folder_Name, "\"), "\") + 
                        "_" + FormatDate("%YYYY%MM%DD-%HH%II%SS", Date()) + ".Zip"
Global FileToAdd.s

UseZipPacker()

If CreatePack(#Zip, Archive_Name)
    Debug "Archive créée: " + Archive_Name
Else
    Debug "Problème pour créer l'archive" + Archive_Name
    End
EndIf

If ExamineDirectory(#Rep, Folder_Name, "*.*")
    
    While NextDirectoryEntry(#Rep) 
        FileToAdd = DirectoryEntryName(#Rep)
        If DirectoryEntryType(#Rep) = #PB_DirectoryEntry_File
            
            Debug "Ajoute: " + FileToAdd
            
            If AddPackFile(#Zip, Folder_Name + "\" + FileToAdd, FileToAdd)
                Debug " + " + FileToAdd
            Else
                Debug " - " + FileToAdd
            EndIf
            
        EndIf
    Wend
    
    ClosePack(#Zip)
    
    FinishDirectory(#Rep)
    MessageRequester("Nom du Fichier Archive: ", Archive_Name)
Else
    Debug "Problème de lecture du répertoire"
EndIf

End
C'est du vite refait, (de mémoire). Il reste à intégrer la gestion des sous-répertoires (pas le temps aujourd'hui) :?

(pour tester rapidement dans l'IDE, met un nom (chemin complet) de répertoire dans les options du compilateur (Onglet 2: Paramètre de l’exécutable))

:wink:

Re: Sauvegarde automatique de fichiers

Publié : lun. 04/janv./2016 17:59
par Micoute
@Marc56 : Je ne m'attendais pas du tout à recevoir du tout fait et je t'en remercie beaucoup.

Re: Sauvegarde automatique de fichiers

Publié : lun. 04/janv./2016 20:48
par Ar-S
@micoute, pour un système de backup digne de ce nom, , il faudrait tout de même vérifier l'intégrité des fichiers archivés(d'une manière ou d'une autre via md5 ou filesize au pire).

Re: Sauvegarde automatique de fichiers

Publié : mar. 05/janv./2016 8:37
par Micoute
Merci du conseil, je ferai pour le mieux !

Re: Sauvegarde automatique de fichiers

Publié : mar. 05/janv./2016 9:27
par Marc56
Hello Micoute,

Voila la version avec prise en compte des sous-répertoires
(et correction d'un bug qui faisait que le nom de fichier archive pouvait être le répertoire n-2 si le DnD passait un '\' final)

La récursivité du scan de répertoires est basée sur une procédure donnée par CLS en 2009
(Edit: Condensé d'un code donné par Flype en 2004) :wink:
Code de CLS http://www.purebasic.fr/french/viewtopic.php?f=1&t=9932
J'ai inséré les commandes de compression de fichier en plus de l'affichage simple

Je me sert de ce programme tous les jours pour sauvegarder mes dossiers projets PB et autres langages à chaque grande étape, mais n'ayant pas avant aujourd'hui étudié les fonctions de compression de PB, j'utilisais 7zG.exe avec RunProgram() pour la partie compression.

Code : Tout sélectionner

; Sauvegarde Dossier vers un .Zip horodaté
; Créé une archive Zip datée avec un dossier reçu par D&D
; (C)Marc56 - 05/01/16
;
; v1.1 - 05/01/16
; - Suppression de l'\' final s'il existe
; - Prise en compte des sous-répertoires
;
; Utilisation
; 1. Compiler ce programme
; 2. Le copier dans le dossier d'archive
; 3. Créer un raccourci sur le bureau
; 4. Faire un drag'n'drop du dossier à archiver sur l'icône
; 5. Le .Zip se trouve dans le dossier d'archive avec le nom Zip_<répertoire>_YYYYMMDD_HHMMSS.zip

EnableExplicit

Enumeration
    #Rep
    #Zip
EndEnumeration

; -- Le programme DOIT recevoir un dossier à archiver par D&D
If Not CountProgramParameters()
    MessageRequester("Pas de Dossier à Archiver",
                     "Aucun paramètre n'a été transmis" + Chr(10) +
                     "Faites glisser un dossier sur l'icône du programme.", 48)
    End
EndIf

; -- Le nom du dossier reçu par D&D (supprimer l'\ final s'il y a a un)
Global Folder_Name.s = RTrim(ProgramParameter(0), "\")

; -- Nom de l'archive générée (Zip_<nom du dossier>_<date-heure-archivage>.Zip)
Global Archive_Name.s = "Zip_" +
                        StringField(Folder_Name, CountString(Folder_Name, "\") +1, "\") +
                        "_" + FormatDate("%YYYY%MM%DD-%HH%II%SS", Date()) + ".Zip"
Global FileToAdd.s

UseZipPacker()

If CreatePack(#Zip, Archive_Name)
    Debug "OK: Archive créée: " + Archive_Name
Else
    Debug "HS: Problème pour créer l'archive " + Archive_Name
    End
EndIf

; -- Scan des sous-rép (By CLS 2009 http://www.purebasic.fr/french/viewtopic.php?f=1&t=9932)
; -- Adapté pour zipper des fichiers avec sous-répertoires
Procedure Scan_Directory(Dir_Name.s, Level = 0) 
    Protected s_name.s, s_type
    If Right(Dir_Name, 1) <> "\" 
        Dir_Name + "\"
    EndIf
    If ExamineDirectory(Level, Dir_Name, "*")
        While NextDirectoryEntry(Level)
            s_name = DirectoryEntryName(Level) : s_type = DirectoryEntryType(Level)
            Select s_type                    
                Case #PB_DirectoryEntry_File
                    FileToAdd.s = Dir_Name + s_name
                    If AddPackFile(#Zip, FileToAdd, FileToAdd)
                        Debug " + " + FileToAdd
                    Else
                        Debug " - " + FileToAdd
                    EndIf                  
                Case #PB_DirectoryEntry_Directory
                    If s_name <> "." And s_name <> ".."
                        Scan_Directory(Dir_Name + s_name, Level + 1)
                    EndIf     
            EndSelect
        Wend
        FinishDirectory(Level)
    EndIf
EndProcedure

Scan_Directory(Folder_Name)

ClosePack(#Zip)
MessageRequester("Nom du Fichier Archive: ", Archive_Name)

End
C'est volontairement expurgé pour rester didactique.
À toi d'ajouter ce dont tu as besoin:
Exemple:
- Barre de progression et/ou fenêtre indiquant les fichiers ajoutés
- Contrôle d'intégrité comme indiqué par Ar-S

Have a fun
:)

Re: Sauvegarde automatique de fichiers

Publié : mar. 05/janv./2016 9:42
par Marc56
Spock a écrit :...
La récursivité du scan de répertoires est basée sur une procédure donnée par CLS en 2009
...
et condensé par Flype en 2004 (tiré d'un code anglais) :)
Ah, Ok, merci de la précision Spock, je corrige :wink:
(Difficile de connaitre l'origine de telle ou telle fonction sans (C) dans les sources)

Re: Sauvegarde automatique de fichiers

Publié : mar. 05/janv./2016 9:54
par Marc56
Ooops 8O
Il y a un oubli dans ma dernière version: l'archive contient le chemin complet des fichiers au lieu du chemin relatif :?
(je n'avais pas testé avec un dossier au niveau n+2 et +)

Re: Sauvegarde automatique de fichiers

Publié : mar. 05/janv./2016 11:24
par Marc56
Spock a écrit :...merci pour tes codes
Merci Spock :wink:

Version 1.2
  • Les sorties Debug sont remplacées par une fenêtre d'info (listeview)
  • L'archive contient désormais le chemin relatif des fichiers et non pas le chemin absolu.
  • Le code reste horrible :mrgreen: 8O :?

Code : Tout sélectionner

; Sauvegarde Dossier vers un .Zip horodaté
; Créé une archive Zip datée avec un dossier reçu par D&D
; (C)Marc56 - 05/01/16
;
; v1.2 - 05/01/16
; - Suppression de l'\' final s'il existe
; - Prise en compte des sous-répertoires
; - Ajout d'une fenêtre d'info (à la place des Debug)
; - L'archive est créée en chemin relatif et non plus absolu
;
; Utilisation
; 1. Compiler ce programme
; 2. Le copier dans le dossier d'archive
; 3. Créer un raccourci sur le bureau
; 4. Faire un drag'n'drop du dossier à archiver sur l'icône
; 5. Le .Zip se trouve dans le dossier d'archive avec le nom Zip_<répertoire>_YYYYMMDD_HHMMSS.zip

EnableExplicit

Enumeration
    #Rep
    #Zip
    #Font_ID
    #Window_0
    #Log
EndEnumeration

; -- Le programme DOIT recevoir un dossier à archiver par D&D
If Not CountProgramParameters()
    MessageRequester("Pas de Dossier à Archiver",
                     "Aucun paramètre n'a été transmis" + Chr(10) +
                     "Faites glisser un dossier sur l'icône du programme.", 48)
    End
EndIf

; -- Le nom du dossier reçu par D&D (supprimer l'\ final s'il y a a un)
Global Folder_Name.s = RTrim(ProgramParameter(0), "\")

; -- Nom de l'archive générée (Zip_<nom du dossier>_<date-heure-archivage>.Zip)
Global Folder_BaseArchive.s = StringField(Folder_Name, CountString(Folder_Name, "\") +1, "\")
Global Path_To_Remove.s = RemoveString(Folder_Name, Folder_BaseArchive)

Global Archive_Name.s = "Zip_" +
                        Folder_BaseArchive +
                        "_" + FormatDate("%YYYY%MM%DD-%HH%II%SS", Date()) + ".Zip"
Global FileToAdd.s, FileInArchive.s

LoadFont(#Font_ID,"Consolas", 9) : SetGadgetFont(#PB_Default, FontID(#Font_ID))
OpenWindow(#Window_0, 0, 0, 600, 500, "Folder Zip and Stamp", #PB_Window_SystemMenu | #PB_Window_ScreenCentered)
ListViewGadget(#Log, 10, 10, 580, 480)
AddGadgetItem(#Log, -1, "Chemin reçu par DnD : " + Folder_Name)
AddGadgetItem(#Log, -1, "Répertoire de base  : " + Folder_BaseArchive)
AddGadgetItem(#Log, -1, "Chemin à enlever    : " + Path_To_Remove)

UseZipPacker()

If CreatePack(#Zip, Archive_Name)
    AddGadgetItem(#Log, -1, "OK: Archive créée: " + Archive_Name)
Else
    AddGadgetItem(#Log, -1, "HS: Problème pour créer l'archive " + Archive_Name)
    End
EndIf

AddGadgetItem(#Log, -1, "---------- Fichier(s) Ajouté(s) ----------")

; -- Scan des sous-rép (By CLS 2009 http://www.purebasic.fr/french/viewtopic.php?f=1&t=9932)
; -- Basé sur code de Flype en 2004 http://www.purebasic.fr/french/viewtopic.php?f=3&t=679
; -- Adapté pour zipper des fichiers avec sous-répertoires
Procedure Scan_Directory(Dir_Name.s, Level = 0) 
    Protected s_name.s, s_type
    If Right(Dir_Name, 1) <> "\" 
        Dir_Name + "\"
    EndIf
    If ExamineDirectory(Level, Dir_Name, "*")
        While NextDirectoryEntry(Level)
            s_name = DirectoryEntryName(Level) : s_type = DirectoryEntryType(Level)
            Select s_type                    
                Case #PB_DirectoryEntry_File
                    FileToAdd.s   = Dir_Name + s_name
                    FileInArchive = RemoveString(FileToAdd, Path_To_Remove)
                    If AddPackFile(#Zip, FileToAdd, FileInArchive)
                        AddGadgetItem(#Log, -1, " + " + FileInArchive)
                    Else
                        AddGadgetItem(#Log, -1, " - " + FileInArchive)
                    EndIf                  
                Case #PB_DirectoryEntry_Directory
                    If s_name <> "." And s_name <> ".."
                        Scan_Directory(Dir_Name + s_name, Level + 1)
                    EndIf     
            EndSelect
        Wend
        FinishDirectory(Level)
    EndIf
EndProcedure

Scan_Directory(Folder_Name)

ClosePack(#Zip)
AddGadgetItem(#Log, -1, "---------- Ajout des Fichier(s) Terminé -------------")
AddGadgetItem(#Log, -1, "Nom du Fichier Archive: " + Archive_Name)

Global Event
Repeat
    Event = WaitWindowEvent(50)
Until Event = #PB_Event_CloseWindow

End
Edit 11:36 Correction du nom de fichier archive qui doublait le nom de dossier.

:idea: Tiens, et si j'intégrais ça à mon Desk ? (encore une ligne de plus dans la Todo :roll: :mrgreen: )

Enjoy
:)

Re: Sauvegarde automatique de fichiers

Publié : mer. 06/janv./2016 9:29
par Marc56
Pour les éventuels utilisateurs ayant besoin de cet utilitaire et n'ayant pas leur compilateur PB à disposition (ex: déplacement chez un client), j'ai créé une page avec l'EXE et le manuel.

Voir lien en signature. (FolderZipStamp)
(Toujours Freeware, même pour usage pro)

Oui, je suis pas trop doué pour trouver des noms à mes programmes :roll:

Enjoy.
:)