Vb10 - méthode de sauvegarde par serialization

Soyez le premier à donner votre avis sur cette source.

Snippet vu 5 906 fois - Téléchargée 17 fois

Contenu du snippet

Voila une méthode de sauvegarde par sérialisation, càd la sauvegarde d'un ensemble.
Dans mon exemple, je sérialise une structure contenant 3 valeurs dans un fichier.
Au lieu d'utiliser la structure d'un fichier INI vous pourrez grâce ce code commencer votre propre gestion de sauvegarde.

En pratique...
J'enregistre ma déclaration dans un fichier:
> "CheminNotepad" = "C:\Windows\Notepad.exe"
J'utilise n'importe ou dans mon code la lecture de cette déclaration:
> Dim JeVeuxRecupererLeChemin As String = Class.LitMoiLaValeureDeCetteDeclaration("CheminNotepad")
Résultat:
JeVeuxRecupererLeChemin = "C:\Windows\Notepad.exe"

Mon organisation .net:
Fichier Class

-Imports ***

--Class clsSauvegarde
(gère les fonctions de sauvegardes)

---Class BackupPath
(ajoute une nouvelle entrée de données)
---Structure Parametres
(schéma contenant des données structurées)

Code pour tester la source:
Public Sub MonCodeTest()
clsSauvegarde.AddPath("AppExe", Application.ExecutablePath)
clsSauvegarde.AddPath("AppPath", Application.StartupPath)

Dim CheminCourant As String
Dim ParamCheminCourant As clsSauvegarde.BackupPath.Parametres

CheminCourant = clsSauvegarde.GetPath("AppPath")
ParamCheminCourant = clsSauvegarde.GetPathParam("AppPath")
If ParamCheminCourant.Attribut = FileAttribute.Directory Then
MessageBox.Show(CheminCourant, "c'est un repertoire !")
ElseIf ParamCheminCourant.Attribut = FileAttribute.Normal Then
MessageBox.Show(CheminCourant, "c'est un fichier !")
Else
MessageBox.Show(CheminCourant, "A un attribut: " & ParamCheminCourant.Attribut.ToString)
End If

ParamCheminCourant = clsSauvegarde.GetPathParam("AppExe")
If ParamCheminCourant.Attribut = FileAttribute.Directory Then
MessageBox.Show(ParamCheminCourant.Nom, "c'est un repertoire !")
ElseIf ParamCheminCourant.Attribut = (FileAttribute.Normal Or FileAttribute.Archive) Then
MessageBox.Show(ParamCheminCourant.Nom, "c'est un fichier !")
Else
MessageBox.Show(ParamCheminCourant.Nom, "A un attribut: " & ParamCheminCourant.Attribut.ToString)
End If
End Sub

Source / Exemple :


Imports System.Runtime.Serialization.Formatters.Binary
Imports System.IO

Public Class clsSauvegarde
    Shared CheminFichierParam As String = "Parametres.bin"

    Public Class BackupPath
        Public Shared myBackupPath() As BackupPath.Parametres

        <Serializable()>
        Public Structure Parametres
            Public Nom As String
            Public Chemin As String
            Public Attribut As FileAttribute
        End Structure
        Sub New()

        End Sub
        Sub New(ByVal NomVariable As String, ByVal Chemin As String)
            Dim bNewEntry As Boolean

            'Charge le tableau depuis le fichier
            myBackupPath = clsSauvegarde.GetPaths()

            'Si le fichier n'existe pas; donc on initialise le tableau
            If myBackupPath Is Nothing Then
                bNewEntry = True
                ReDim myBackupPath(0)
            Else
                bNewEntry = False
                ReDim Preserve myBackupPath(myBackupPath.Length)
            End If

            'Premiere entrée ?
            If bNewEntry = False Then
                'NON, l'entrée a enregistré existe ?
                If ExistPath(NomVariable) = True Then
                    'OUI, alors update
                    UpdatePath(NomVariable, Chemin)
                    Exit Sub
                Else
                    'NON, alors save
                    SavePath(NomVariable, Chemin)
                End If
            Else
                'OUI, nouvelle entrée > save
                SavePath(NomVariable, Chemin)
            End If

        End Sub
    End Class

    Shared Sub UpdatePath(ByVal NomVariable As String, ByVal NouveauChemin As String)
        Dim myPaths() As clsSauvegarde.BackupPath.Parametres = clsSauvegarde.GetPaths()
        Dim iFile As Integer = 0
        Dim iSave As Integer = 0
        Dim isUpdated As Boolean = False

        'curPathParam = fichier lu dans le fichier params
        For Each curPathParam As BackupPath.Parametres In myPaths
            'chrBackUp = ce qui viens d'être ajouté dans le tableau
            For Each curBackupUp As BackupPath.Parametres In BackupPath.myBackupPath
                'Si le nom existe alors mettre à jour
                If curBackupUp.Nom = curPathParam.Nom Then
                    curBackupUp.Chemin = NouveauChemin
                    curBackupUp.Attribut = New IO.DirectoryInfo(NouveauChemin).Attributes
                    BackupPath.myBackupPath(iFile) = curBackupUp
                    isUpdated = True
                    Exit For
                End If
                iSave += 1
            Next
            If isUpdated = True Then Exit For
            iFile += 1
        Next

        'Sauvegarde
        If isUpdated = True Then
            Dim FluxDeFichier As FileStream = File.Create(CheminFichierParam)
            Dim Serialiseur As New BinaryFormatter
            Dim newBackupPath() As BackupPath.Parametres = Nothing

            'Supprime la nouvelle entrée qui ne servira pas
            ReDim newBackupPath(BackupPath.myBackupPath.Length - 2)
            Array.Copy(BackupPath.myBackupPath, newBackupPath, BackupPath.myBackupPath.Length - 1)
            BackupPath.myBackupPath = newBackupPath

            Serialiseur.Serialize(FluxDeFichier, BackupPath.myBackupPath)
            FluxDeFichier.Close()

            'rafraichit le tableau
            BackupPath.myBackupPath = clsSauvegarde.GetPaths()
        End If
    End Sub

    Shared Function ExistPath(ByVal NomVariable As String) As Boolean
        Dim myPaths() As clsSauvegarde.BackupPath.Parametres = clsSauvegarde.GetPaths()
        If myPaths Is Nothing Then Return False

        For Each curPath As BackupPath.Parametres In myPaths
            If curPath.Nom = NomVariable Then Return True
        Next
        Return False
    End Function

    Shared Sub AddPath(ByVal NomVariable As String, ByVal Chemin As String)
        Dim NewEntry As New BackupPath(NomVariable, Chemin)
    End Sub

    Shared Sub SavePath(ByVal NomVariable As String, ByVal Chemin As String)
        Dim curID As Integer = (BackupPath.myBackupPath.Length - 1)

        BackupPath.myBackupPath(curID).Nom = NomVariable
        BackupPath.myBackupPath(curID).Chemin = Chemin
        BackupPath.myBackupPath(curID).Attribut = New IO.DirectoryInfo(Chemin).Attributes

        'Sauvegarde vers le fichier
        Dim FluxDeFichier As FileStream = File.Create(CheminFichierParam)
        Dim Serialiseur As New BinaryFormatter
        Serialiseur.Serialize(FluxDeFichier, BackupPath.myBackupPath)
        FluxDeFichier.Close()

        'Actualise le tableau
        BackupPath.myBackupPath = clsSauvegarde.GetPaths()
    End Sub

    Protected Shared Function GetPaths() As BackupPath.Parametres()
        If File.Exists(CheminFichierParam) Then
            Dim tmpBackUp() As BackupPath.Parametres
            Dim FluxDeFichier As Stream = File.OpenRead(CheminFichierParam)
            Dim Deserialiseur As New BinaryFormatter()
            tmpBackUp = CType(Deserialiseur.Deserialize(FluxDeFichier), BackupPath.Parametres())
            FluxDeFichier.Close()
            Return tmpBackUp
        End If
        Return Nothing
    End Function

    Shared Function GetPath(ByVal NomVariable As String) As String
        Dim rt As String = Nothing

        If File.Exists(CheminFichierParam) Then
            Dim myPaths() As clsSauvegarde.BackupPath.Parametres = clsSauvegarde.GetPaths()
            For Each curPathParam As BackupPath.Parametres In myPaths
                If NomVariable = curPathParam.Nom Then
                    rt = curPathParam.Chemin
                    Exit For
                End If
            Next
        End If
        Return rt
    End Function

    Shared Shadows Function GetPathParam(ByVal NomVariable As String) As clsSauvegarde.BackupPath.Parametres
        Dim rt As clsSauvegarde.BackupPath.Parametres = Nothing

        If File.Exists(CheminFichierParam) Then
            Dim myPaths() As clsSauvegarde.BackupPath.Parametres = clsSauvegarde.GetPaths()
            For Each curPathParam As BackupPath.Parametres In myPaths
                If NomVariable = curPathParam.Nom Then
                    rt = curPathParam
                    Exit For
                End If
            Next
        End If
        Return rt
    End Function

End Class

Conclusion :


En sortie nous avons un fichier codé qui représente un "code managé?" compris par le Framework.

Utilisation d'un fichier en lecture/écriture avec Stream/FileStream.
Lecture = Désérialisation < Stream
Ecriture = Sérialisation < FileStream

La serialization est effectué par BinaryFormatter par l'intermédiaire de System.Runtime.Serialization.Formatters.Binary

La possibilité d'avoir accès rapidement a une variable écrit dans un fichier:
ParamCheminCourant = clsSauvegarde.GetPathParam("AppExe")

En seconde approche j'étudierai ce que peut offrir: System.Runtime.Serialization
Peut-être l'utilisation d'entrée et sortie cryptée ?

A voir également

Ajouter un commentaire

Commentaires

Messages postés
1172
Date d'inscription
jeudi 24 mai 2007
Statut
Membre
Dernière intervention
28 septembre 2013
1
@ Nhenry, comme le montre mon tuto sur les classes métier j'utilise cette méthode à chaque fois. DOnc pour répondre à ta question.
La relecture d'un fichier sérializé suite à des modif et possible que si il y a ajout de propriété si il y a modification de type le fichier antérieur sera illisible (voir source sur compte bancaire, fichier class). La sérialisation n'a rien avoir avec une bdd, elle sert juste à compiler une sommes de valeurs de type et forme différente. Dans mes sources et classes vous verrez que je commence une ligne de valeurs par un GUID, qui pourrait servir à identifier la ligne du fichier à supprimer et à remplacer lors d'un enregistrement, mais comme il faut désérializer avant je ne pense pas que cela soit pertinent comme démarche. Au plaisir de vous lire sur le sujet. Bonne prog PS : Duke, sérialize plutot ta classe entiére ;) kenavo Sieur
Messages postés
550
Date d'inscription
jeudi 12 octobre 2006
Statut
Membre
Dernière intervention
6 juin 2015
3
Henry, dis moi tout ^^
Merci d'avance ;)
Messages postés
14689
Date d'inscription
vendredi 14 mars 2003
Statut
Modérateur
Dernière intervention
8 août 2020
144
je pense que l'on ne s'est pas compris :
Version 1 : J'enregistre mes données
Ensuite, petite mise à jour
Version 2 : est-ce que je récupère les données enregistrées avec la version 1 ?

Pour en faire une base de données, il y a un point à faire attention, c'est que ce n'est pas toujours garanti que la longueur soit fixe (chaines).
Donc un beau travail en perspective.
Messages postés
550
Date d'inscription
jeudi 12 octobre 2006
Statut
Membre
Dernière intervention
6 juin 2015
3
Je partage une méthode d'approche à la sérialization; tout reste à faire ^^

Pour le moment, la structure sérialisé vers un fichier se fait par écrasement, donc...
Perte de données :(
Aucune édition ou ajout n'est possible après la création du fichier.

Ce qui sera amélioré dans mes prochaines recherches...
Utiliser ce fichier comme on le ferait pour avec une base de donnée ou un fichier ressource.
Messages postés
14689
Date d'inscription
vendredi 14 mars 2003
Statut
Modérateur
Dernière intervention
8 août 2020
144
Question,

Que ce passe-t-il si on change légèrement la classe précédemment sérialisée, on perd toutes les données ou il ne renseigne que les données connues ? (pareil si on change le code d'une fonction de la classe ? )
(Mise à jour de programme par exemple)

Bravo et merci, en tout cas, pour ton activité et pour ta conscience de l'utilité du partage :)

Vous n'êtes pas encore membre ?

inscrivez-vous, c'est gratuit et ça prend moins d'une minute !

Les membres obtiennent plus de réponses que les utilisateurs anonymes.

Le fait d'être membre vous permet d'avoir un suivi détaillé de vos demandes et codes sources.

Le fait d'être membre vous permet d'avoir des options supplémentaires.