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 |
Partager