IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Windows Forms Discussion :

[VB.NET] Remplacement de fichier, section critique


Sujet :

Windows Forms

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre éclairé
    Profil pro
    Inscrit en
    Juillet 2004
    Messages
    344
    Détails du profil
    Informations personnelles :
    Âge : 40
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations forums :
    Inscription : Juillet 2004
    Messages : 344
    Par défaut [VB.NET] Remplacement de fichier, section critique
    Bonjour,

    Je souhaite réaliser une classe permettant le remplacement de fichier d'une manière sécurisée. Je m'explique ...

    Je voudrais faire, comme pour une transaction de base de données, un système de Commit et de RollBack. Cependant, le but est de limiter au maximum les erreurs d'accès aux fichiers traités (fichier source, fichier remplacé, sauvegarde, ...).

    Voila comment j'aimerais procéder.
    1- Je verrouille mon fichier à copier et mon fichier à remplacer.
    2- Je fais une copie de mon fichier à remplacer (que je verrouille).
    3- J'effectue le remplacement de mon fichier.
    4- Le commit supprime la copie faite en 2 et deverrouille les fichiers.
    5- Le Rollback restaure le fichier à remplacer et deverrouille les fichiers.

    Maintenant, les problèmes .... Comment verrouiller un fichier ???

    J'ai pensé tout simplement à l'ouvrir en mode exclusif. Cependant comment remplacer un fichier ouvert ???? Absurde .... Je suis donc obligé de
    1- Ferme le fichier (deverrouiller).
    2- Remplacer le fichier.
    3- Ouvrir le fichier (verrouiller).

    Autre problème, comment rendre cette séquence atomique ???? Je veux être sûr qu'aucun autre programme ouvre le fichier lors de cette séquence.

    Merci de votre aide à ce sujet.

  2. #2
    Membre émérite Avatar de Yorglaa
    Profil pro
    Inscrit en
    Janvier 2004
    Messages
    845
    Détails du profil
    Informations personnelles :
    Âge : 54
    Localisation : Suisse

    Informations forums :
    Inscription : Janvier 2004
    Messages : 845
    Par défaut
    une suggestion toute bête...

    en renommant le fichier avec une extension différente (changement de nom + de l'extension) ?

    ça a le mérite de "cacher" le fichier en cours de traitement aux autres utilisateurs qui pourraient s'attendre à un nom et/ou un type de fichier déterminé.

    avec évidemment le renommage inverse une fois l'opération terminée (commit).

  3. #3
    Membre éclairé
    Profil pro
    Inscrit en
    Juillet 2004
    Messages
    344
    Détails du profil
    Informations personnelles :
    Âge : 40
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations forums :
    Inscription : Juillet 2004
    Messages : 344
    Par défaut
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    ça a le mérite de "cacher" le fichier en cours de traitement aux autres utilisateurs
    C'est vrai, ca ne me garantit pas que personne n'ouvrira mon fichier ...
    Il me faudrait vraiment une garantie .....

  4. #4
    Membre émérite Avatar de Yorglaa
    Profil pro
    Inscrit en
    Janvier 2004
    Messages
    845
    Détails du profil
    Informations personnelles :
    Âge : 54
    Localisation : Suisse

    Informations forums :
    Inscription : Janvier 2004
    Messages : 845
    Par défaut
    tu peux le déplacer dans un répertoire où toi seul a accès avant de commencer à travailler dessus...

    le problème c'est que tu n'as aucune garantie que le fichier n'est pas DEJA ouvert chez quelqu'un avant de commencer à bosser dessus

  5. #5
    Membre éclairé
    Profil pro
    Inscrit en
    Juillet 2004
    Messages
    344
    Détails du profil
    Informations personnelles :
    Âge : 40
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations forums :
    Inscription : Juillet 2004
    Messages : 344
    Par défaut
    Peut-on interdire l'interruption d'un processus pour quelques lignes d'une code ?

  6. #6
    Membre éclairé
    Profil pro
    Inscrit en
    Juillet 2004
    Messages
    344
    Détails du profil
    Informations personnelles :
    Âge : 40
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations forums :
    Inscription : Juillet 2004
    Messages : 344
    Par défaut
    J'ai trouvé une solution en passant par les classes FileStream et BufferedStream pour effectuer mes copies de fichiers ...

    Merci Yorglaa

  7. #7
    Membre émérite Avatar de Yorglaa
    Profil pro
    Inscrit en
    Janvier 2004
    Messages
    845
    Détails du profil
    Informations personnelles :
    Âge : 54
    Localisation : Suisse

    Informations forums :
    Inscription : Janvier 2004
    Messages : 845
    Par défaut
    Pas de quoi...
    tu pourrais nous exposer brièvement ta solution STP ?

    ça peux servir à d'autres qui seraient confrontés à la même problèmatique

  8. #8
    Membre éclairé
    Profil pro
    Inscrit en
    Juillet 2004
    Messages
    344
    Détails du profil
    Informations personnelles :
    Âge : 40
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations forums :
    Inscription : Juillet 2004
    Messages : 344
    Par défaut
    Voici le code d'une classe qui peut simplifier la vie ....

    Biensur, toutes remarques ou corrections sont les bienvenue.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144
    145
    146
    147
    148
    149
    150
    151
    152
    153
    154
    155
    156
    157
    158
    159
    160
    161
    162
    163
    164
    165
    166
    167
    168
    169
    170
    171
    172
    173
    174
    175
    176
    177
    178
    179
    180
    181
    182
    183
    184
    185
    186
    187
    188
    189
    190
    191
    192
    193
    194
    195
    196
    197
    198
    Option Explicit On 
    Option Strict On
     
    Imports System.Security
    Imports System.IO
     
    Public Class CopieFichier
        Implements IDisposable
     
        Private _sources As ArrayList
     
        Private _destinataires As ArrayList
     
        Private _sauvegardes As ArrayList
     
        Private Overloads Sub Copier(ByVal source As FileStream, ByVal destinataire As FileStream)
            Dim tailleSource As Integer
            Dim buffer As Byte()
     
            ' Récupère le contenu du fichier.
            If source.Length > Integer.MaxValue Then
                Throw New TailleFichierException("")
            End If
            tailleSource = CInt(source.Length)
     
            ' Copie le contenu du fichier.
            source.Read(buffer, 0, tailleSource)
            destinataire.SetLength(tailleSource)
            destinataire.Write(buffer, 0, tailleSource)
        End Sub
     
        Private Function Sauvegarder(ByVal fichier As FileStream) As BufferedStream
            Dim sauvegarde As BufferedStream
     
            ' Effectue une sauvegarde du fichier.
            sauvegarde = New BufferedStream(fichier)
     
            ' Retourne le résultat.
            Return sauvegarde
        End Function
     
        Private Sub Restaurer(ByVal copie As Integer)
            Dim sauvegarde As BufferedStream
            Dim destinataire As FileStream
            Dim buffer As Byte()
     
            ' Récupère les éléments de la restauration.
            sauvegarde = DirectCast(_sauvegardes.Item(copie), BufferedStream)
            destinataire = DirectCast(_destinataires.Item(copie), FileStream)
     
            ' Restaure le contenu du fichier de destination.
            destinataire.SetLength(sauvegarde.Length)
            If sauvegarde.Length > 0 Then
                sauvegarde.Read(buffer, 0, CInt(sauvegarde.Length))
                destinataire.Write(buffer, 0, CInt(sauvegarde.Length))
            End If
        End Sub
     
        Private Sub TerminerCopie(ByVal copie As Integer)
            Dim source, destinataire As FileStream
            Dim sauvegarde As BufferedStream
     
            ' Ferme le fichier source.
            source = DirectCast(_sources.Item(copie), FileStream)
            _sources.RemoveAt(copie)
            source.Close()
     
            ' Ferme le fichier destinataire.
            destinataire = DirectCast(_destinataires.Item(copie), FileStream)
            _destinataires.RemoveAt(copie)
            destinataire.Close()
     
            ' Détruit la sauvegarde.
            sauvegarde = DirectCast(_sauvegardes.Item(copie), BufferedStream)
            _sauvegardes.RemoveAt(copie)
            sauvegarde.Close()
        End Sub
     
        Protected Sub Dispose(ByVal disposing As Boolean)
     
            ' Annule la copie des fichiers.
            Try : Me.RollBack()
            Catch erreur As Exception
            End Try
     
            ' Termine la copie.
            If Not _sources Is Nothing Then
                Do While _sources.Count <> 0
                    Me.TerminerCopie(0)
                Loop
            End If
        End Sub
     
        Protected Overrides Sub Finalize()
            Me.Dispose(False)
        End Sub
     
        Public Sub New()
     
            ' Initialise les listes de copies.
            _sources = New ArrayList
            _destinataires = New ArrayList
            _sauvegardes = New ArrayList
        End Sub
     
        Public Sub Dispose() Implements IDisposable.Dispose
     
            ' Annule l'ensemble des copies.
            Me.RollBack()
     
            ' Détruit l'instance.
            Me.Dispose(True)
        End Sub
     
        Public Overloads Sub Copier(ByVal source As String, ByVal destinataire As String)
            Dim fichierDestinataire As FileStream
            Dim sauvegarde As BufferedStream
            Dim fichierSource As FileStream
     
            ' Ouvre le fichier source en mode exclusif.
            fichierSource = New FileStream(source, FileMode.Open, FileAccess.Read, FileShare.None)
     
            ' Ouvre le fichier destinataire en mode exclusif.
            Try : fichierDestinataire = New FileStream(source, FileMode.OpenOrCreate, FileAccess.ReadWrite, FileShare.None)
            Catch erreur As Exception
                If Not fichierSource Is Nothing Then fichierSource.Close()
                Throw erreur
            End Try
     
            Try
                ' Contrôle la taille du fichier source.
                If fichierSource.Length > Integer.MaxValue Then
                    Throw New TailleFichierException("")
                End If
     
                ' Sauvegarde le fichier destinataire.
                sauvegarde = Me.Sauvegarder(fichierDestinataire)
     
                ' Ajoute la copie à la liste.
                _sources.Add(fichierSource)
                _destinataires.Add(fichierDestinataire)
                _sauvegardes.Add(sauvegarde)
     
            Catch erreur As Exception
                If Not fichierSource Is Nothing Then fichierSource.Close()
                If Not fichierDestinataire Is Nothing Then fichierDestinataire.Close()
                Throw erreur
            End Try
        End Sub
     
        Public Sub Commit()
            Dim source, destinataire As FileStream
            Dim index As Integer = 0
     
            Try
                ' Réalise l'ensemble des copies.
                Do While index < _sources.Count
     
                    ' Récupère les fichiers de la copie.
                    source = DirectCast(_sources.Item(index), FileStream)
                    destinataire = DirectCast(_destinataires.Item(index), FileStream)
     
                    ' Copie le contenu.
                    Me.Copier(source, destinataire)
     
                    ' Passe à la copie suivante.
                    index += 1
                Loop
            Catch erreur As Exception
     
                ' Annule les copies réalisées.
                Do While index >= 0
     
                    ' Restaure la copie courante.
                    Try : Me.Restaurer(index)
                    Catch erreur1 As Exception
                    End Try
     
                    ' Passe à la restauration suivante
                    index += 1
                Loop
            End Try
     
            ' Termine l'ensemble des copies.
            Do While _sources.Count <> 0
                Me.TerminerCopie(0)
            Loop
        End Sub
     
        Public Sub RollBack()
     
            ' Termine l'ensemble des copies.
            Do While _sources.Count <> 0
                Me.TerminerCopie(0)
            Loop
        End Sub
     
    End Class

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Vb.Net Lire toutes les sections d'un fichier INI
    Par Magdix dans le forum VB.NET
    Réponses: 8
    Dernier message: 21/01/2009, 17h12
  2. [VB.NET] Import de fichiers d'une machine distante
    Par Bill_Baroud dans le forum ASP.NET
    Réponses: 3
    Dernier message: 03/06/2004, 13h16
  3. Réponses: 2
    Dernier message: 26/05/2004, 17h53
  4. [VB.NET] Importation de fichier texte
    Par Hoegaarden dans le forum Windows Forms
    Réponses: 5
    Dernier message: 25/05/2004, 09h39
  5. [VB.NET] Download de fichiers sur un serveur...
    Par Webman dans le forum ASP.NET
    Réponses: 3
    Dernier message: 19/05/2004, 10h25

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo