Sauvegarde automatique de fichiers

Vous débutez et vous avez besoin d'aide ? N'hésitez pas à poser vos questions
Avatar de l’utilisateur
Micoute
Messages : 2583
Inscription : dim. 02/oct./2011 16:17
Localisation : 35520 La Mézière

Sauvegarde automatique de fichiers

Message 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.
Microsoft Windows 10 Famille 64 bits : Carte mère : ASRock 970 Extreme3 R2.0 : Carte Graphique NVIDIA GeForce RTX 3080 : Processeur AMD FX 6300 6 cœurs 12 threads 3,50 GHz PB 6.20 LTS (x64)
Un homme doit être poli, mais il doit aussi être libre !
Avatar de l’utilisateur
Ar-S
Messages : 9539
Inscription : dim. 09/oct./2005 16:51
Contact :

Re: Sauvegarde automatique de fichiers

Message 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 !
~~~~Règles du forum ~~~~
⋅.˳˳.⋅ॱ˙˙ॱ⋅.˳Ar-S ˳.⋅ॱ˙˙ॱ⋅.˳˳.⋅
W11x64 PB 6.x
Section HORS SUJET : ICI
LDV MULTIMEDIA : Dépannage informatique & mes Logiciels PB
UPLOAD D'IMAGES : Uploader des images de vos logiciels
Marc56
Messages : 2196
Inscription : sam. 08/févr./2014 15:19

Re: Sauvegarde automatique de fichiers

Message 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:
Avatar de l’utilisateur
falsam
Messages : 7317
Inscription : dim. 22/août/2010 15:24
Localisation : IDF (Yvelines)
Contact :

Re: Sauvegarde automatique de fichiers

Message 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.
Configuration : Windows 11 Famille 64-bit - PB 6.20 x64 - AMD Ryzen 7 - 16 GO RAM
Vidéo NVIDIA GeForce GTX 1650 Ti - Résolution 1920x1080 - Mise à l'échelle 125%
Avatar de l’utilisateur
Micoute
Messages : 2583
Inscription : dim. 02/oct./2011 16:17
Localisation : 35520 La Mézière

Re: Sauvegarde automatique de fichiers

Message 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.
Microsoft Windows 10 Famille 64 bits : Carte mère : ASRock 970 Extreme3 R2.0 : Carte Graphique NVIDIA GeForce RTX 3080 : Processeur AMD FX 6300 6 cœurs 12 threads 3,50 GHz PB 6.20 LTS (x64)
Un homme doit être poli, mais il doit aussi être libre !
Marc56
Messages : 2196
Inscription : sam. 08/févr./2014 15:19

Re: Sauvegarde automatique de fichiers

Message 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:
Avatar de l’utilisateur
Micoute
Messages : 2583
Inscription : dim. 02/oct./2011 16:17
Localisation : 35520 La Mézière

Re: Sauvegarde automatique de fichiers

Message par Micoute »

@Marc56 : Je ne m'attendais pas du tout à recevoir du tout fait et je t'en remercie beaucoup.
Microsoft Windows 10 Famille 64 bits : Carte mère : ASRock 970 Extreme3 R2.0 : Carte Graphique NVIDIA GeForce RTX 3080 : Processeur AMD FX 6300 6 cœurs 12 threads 3,50 GHz PB 6.20 LTS (x64)
Un homme doit être poli, mais il doit aussi être libre !
Avatar de l’utilisateur
Ar-S
Messages : 9539
Inscription : dim. 09/oct./2005 16:51
Contact :

Re: Sauvegarde automatique de fichiers

Message 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).
~~~~Règles du forum ~~~~
⋅.˳˳.⋅ॱ˙˙ॱ⋅.˳Ar-S ˳.⋅ॱ˙˙ॱ⋅.˳˳.⋅
W11x64 PB 6.x
Section HORS SUJET : ICI
LDV MULTIMEDIA : Dépannage informatique & mes Logiciels PB
UPLOAD D'IMAGES : Uploader des images de vos logiciels
Avatar de l’utilisateur
Micoute
Messages : 2583
Inscription : dim. 02/oct./2011 16:17
Localisation : 35520 La Mézière

Re: Sauvegarde automatique de fichiers

Message par Micoute »

Merci du conseil, je ferai pour le mieux !
Microsoft Windows 10 Famille 64 bits : Carte mère : ASRock 970 Extreme3 R2.0 : Carte Graphique NVIDIA GeForce RTX 3080 : Processeur AMD FX 6300 6 cœurs 12 threads 3,50 GHz PB 6.20 LTS (x64)
Un homme doit être poli, mais il doit aussi être libre !
Marc56
Messages : 2196
Inscription : sam. 08/févr./2014 15:19

Re: Sauvegarde automatique de fichiers

Message 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
:)
Dernière modification par Marc56 le mar. 05/janv./2016 9:45, modifié 3 fois.
Marc56
Messages : 2196
Inscription : sam. 08/févr./2014 15:19

Re: Sauvegarde automatique de fichiers

Message 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)
Marc56
Messages : 2196
Inscription : sam. 08/févr./2014 15:19

Re: Sauvegarde automatique de fichiers

Message 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 +)
Marc56
Messages : 2196
Inscription : sam. 08/févr./2014 15:19

Re: Sauvegarde automatique de fichiers

Message 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
:)
Marc56
Messages : 2196
Inscription : sam. 08/févr./2014 15:19

Re: Sauvegarde automatique de fichiers

Message 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.
:)
Répondre