Mission 1 : Archivage de données en C#
Contexte : Pour préparer la migration des données, il faudrait créer un script C# qui permettra de récupérer tous les fichiers et les copier dans plusieurs fichiers zip dans un dossier précis.
App.Config : Ce fichier est le fichier de configuration du projet c#. On y trouvera
une section avec les clés correspondants au nom des dossiers où se trouvent les
fichiers, et qui ont pour valeur le chemin permettant d'accéder à ce dossier.
Il y a cependant une clé nommée LastRun qui a pour valeur une date initialisée
"01/01/2000 00:00:00" qui sera comparée à la date de modification de chaque
fichier. Si la date du fichier est antérieure à celle de LastRun, on ne la compte pas
parmi les fichiers à zipper. LastRun sera mis à jour après le lancement du script.
ConfigReader.cs : Ce fichier constitue le coeur du projet. C'est ici que toutes les
fonctions seront programmées.
ArchiveConfig - une classe scellée contenant des variables ayant pour nom les
clés de la section App.Config.
Program.cs : Il s'agit du fichier où nous allons appeler la fonction principale pour
archiver les fichiers.
Détail des fonctions :
J'ai commencé par créer une classe scellée, qui comportera uniquement des
variables qui seront utilisées plus tard.
La première fonction créée est ReadConfiguration().
Cette fonction a pour but de récupérer les valeurs présente dans l'App.Config.
Les premières lignes permettent d'ouvrir le fichier de configuratin App.Config,
et d'utiliser l'environnement que nous souhaitons. Ici, l'environnement est CLK.
Avant de récupérer les valeurs, il faut vérifier si la section CLK n'est pas vide.
Toutes les valeurs du App.Config sont des chaines de caractères sauf pour
LastRun qui est une date.
On créé donc un dictionnaire config.PathDict pour récupérer les valeurs
correspondant au chemin de chaque dossier à zipper et un second dictionnaire
config.TargetPathDict pour récupérer le chemin de destination pour chaque zip.
On remarque également que la longueur du dictionnaire TargetPathDict est plus
long que le premier. En effet, il y a deux clés en plus. MAX_ZIP_SIZE_BYTE et
MAX_NUM_OF_FILES_IN_ZIP correspondant à la limite de bits et de fichiers par
zip. Ils ne seront pas comptés car la boucle d'archivage de fichier se fera sur
le premier dictionnaire PathDict.
La deuxième fonction est une private fonction nommée getConfigValue prenant
en paramètre une chaine de caractères. Cette fonction va simplement renvoyer la
valeur associée à la clé du App.config. Elle sera utilisée dans la fonction qui suit.
La prochaine fonction à créer est une procédure qui permet de zipper un certains
nombre de fichiers.
La fonction se nomme CompressToZip qui prend en paramètre le chemin de
destination, le nom du fichier choisi pour le ZIP qui va être le nom de chaque clé
(qui correspond au nom de chaque dossier à zipper) suivi de la date "06152023"
du fichier le plus ancien et du plus récent (ex : TEST_06102023_06152023.zip), et
une liste qui comportera les fichiers à mettre dans un fichier ZIP. Le niveau de
compression est à 9 car c'est le niveau de compression le plus élevé. Il est
possible qu'il y ai parfois deux fichiers ZIP avec le même nom. Pour éviter cela,
j'ai crée une condition qui ajoute un suffixe (_1, _2...) si il existe déjà un fichier
ZIP avec le nom entré en paramètre.
La dernière fonction est la fonction principale où les fonctions précédentes sont
utilisées. La fonction se nomme Archive().
Pour commencer, j'ai crée une variable i dans un boucle qui va parcourir les
chemin de dossiers sources, qui correspond à l'index dans le
dictionnaire targetPath, où se trouve le chemin de destination des fichiers. A
chaque tour de boucle, on change de dossier source donc on ajoute 1 à i pour
changer de dossier de destination.
Dans cette première boucle, on y trouve deux autres variables : actualFileCount
et actualSizeOfFiles.
Nous souhaitons que pour chaque fichier ZIP, il y ait un maximum de 100 fichiers
ou que le fichier ZIP ait une taille maximale de 20 Mo. actualFileCount est utilisé
pour compter le nombre de fichier qu'on va mettre dans un fichier ZIP, et
actualSizeOfFile pour compter le nombre total de bits pour un nombre de
fichiers. Le chemin de chaque fichier seront mis dans une liste nommée pathList.
C'est à chaquefois que l'on va ajouter un fichier dedans, que l'on va actualiser
actualFileCount et actualSizeOfFile. Pour ajouter la taille d'un fichier (int) dans
notre variable, on utilise .Lenght.
Etant donné que l'on veut pour chaque fichier ZIP un nom avec la date du fichier
le plus ancien et le plus récent, nous devons parcourir les fichiers rangé par date
de création. C'est le meilleur moyen pour trouver la date la plus ancienne et la
plus récente, car le fichier le plus ancien se trouve à l'index 0 de la liste des
fichiers, et le fichier le plus récent au dernier index.
La première chose à faire lorsque l'on parcourt les fichiers, est de vérifier
longueur du nom chemin du fichier. Pourquoi? Car sa longueur ne peut pas
dépasser une taille de 260 caractères. Donc si le fichier en cours d'utilisation
a une taille supérieure à 260 caractères, on affiche un message d'erreur (détail
du log plus tard...) et on continue notre boucle.
utilisées. La fonction se nomme Archive().
Pour commencer, j'ai crée une variable i dans un boucle qui va parcourir les
chemin de dossiers sources, qui correspond à l'index dans le
dictionnaire targetPath, où se trouve le chemin de destination des fichiers. A
chaque tour de boucle, on change de dossier source donc on ajoute 1 à i pour
changer de dossier de destination.
Dans cette première boucle, on y trouve deux autres variables : actualFileCount
et actualSizeOfFiles.
Nous souhaitons que pour chaque fichier ZIP, il y ait un maximum de 100 fichiers
ou que le fichier ZIP ait une taille maximale de 20 Mo. actualFileCount est utilisé
pour compter le nombre de fichier qu'on va mettre dans un fichier ZIP, et
actualSizeOfFile pour compter le nombre total de bits pour un nombre de
fichiers. Le chemin de chaque fichier seront mis dans une liste nommée pathList.
C'est à chaquefois que l'on va ajouter un fichier dedans, que l'on va actualiser
actualFileCount et actualSizeOfFile. Pour ajouter la taille d'un fichier (int) dans
notre variable, on utilise .Lenght.
Etant donné que l'on veut pour chaque fichier ZIP un nom avec la date du fichier
le plus ancien et le plus récent, nous devons parcourir les fichiers rangé par date
de création. C'est le meilleur moyen pour trouver la date la plus ancienne et la
plus récente, car le fichier le plus ancien se trouve à l'index 0 de la liste des
fichiers, et le fichier le plus récent au dernier index.
La première chose à faire lorsque l'on parcourt les fichiers, est de vérifier
Les conditions ont un ordre très précis pour éviter tout problème lors de
l'archivage. La seconde condition vérifie si la taille du fichier est supérieur à la
taille maximale définie pour un fichier ZIP. Si c'est le cas, on crée va zipper ce
fichier seul et continuer la boucle.
La troisième condition vérifie si la liste des fichiers à atteint son maximum en
terme de nombre de fichier OU en terme de taille. Si un des deux est vrai, on zip
les fichiers présent dans la liste.
Pour chaque fichier, on vérifie si sa date est au dessus de LastRun et si c'est le
cas, on l'ajoute à la liste des fichiers à zipper et on met à jour les compteurs
actualFileCount et actualSizeOfFiles. Sinon, on renvoie une erreur.
Enfin, si la liste contient au moins un fichier, on le zippe.
Pour en revenir au logger, un log permet d'afficher des informations lorsque le
programme est en cours. Le log utiliser vient de Log4Net est il est très efficace.
J'ai fait en sorte d'afficher les informations dans un fichier log.txt pour que les
personnes qui souhaitent utiliser mon code puisse accéder à ces informations.
Il est pratique d'utiliser un log car il nous permet de voir si il y a certains
problème et d'avertir (dans mon cas), si un fichier ne peut pas être archivé.
Il y a plusieurs types de messages : INFO, DEBUG, ERROR et WARN et FATAL.
J'ai uniquement utilisé INFO et ERROR.
Voici le résultat final (une partie seulement) :
Ici une partie de l'archivage. Le nom du dossier avec la date du fichier le plus
ancien et du plus récent.
Et le log (exemple) :