Bonsoir, suite à une autre discussion, j'ouvre celle-ci pour demander des avis quant à la conception d'un programme de recherche de doublons de fichiers.
En préambule, je sais que de tels programmes existent et je ne cherche pas à réinventer la roue, juste me servir de ce programme comme support d'apprentissage
Rentrons maintenant dans le vif du sujet.
En premier lieu, suite aux conseil avisés reçus auparavant, tout le programme fonctionnera en mode console. Ce n'est qu'une fois fonctionnel que je l'adapterai sous Qt afin d'en faire un programme graphique. En conséquence, le programme devra être bâti pour nécessiter le moins de modifications possible lors de son adaptation sous Qt.
J'ai réfléchi sur papier à la conception des objets, et fait les ébauches suivantes des headers :
- classe DirsToScan : contient les noms des dossiers à scanner et les méthodes d'ajout/suppression de dossier à la classe, ainsi que des méthodes représentant les options à choisir par l'utilisateur pour tous les dossiers.
- classe Directory : utilisée par DirsToScan, contient le chemin absolu d'un dossier à scanner, et les options qui lui sont liées.
- classe Scan : contient le code pour scanner les dossier Directory pointés dans une instance DirsToScan, avec des options diverses.
- classe Profile : charge et sauve dans un fichier un profil utilisateur. Servira particulièrement dans cette ébauche console à fournir les données au programme sans intervention d'un utilisateur.
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 #ifndef DIRSTOSCAN_H #define DIRSTOSCAN_H /* La classe DirsToScan représente un ensemble de dossiers à scanner. Chaque dossier à scanner est représenté par la classe Directory. Dans la classe, les objets de type Directory sont pointés dans un vector. ** Méthodes et accesseurs publiques : ** Les méthodes addDir() et delDir() permettent respectivement d'ajouter et de supprimer un dossier. La méthode addDir() autorise des paramètres de récursivité dans les sous-dossiers, et un paramètre de protection contre le déplacement ou l'effacement des fichiers contenus dans le dossier ajouté (ainsi que ses sous-dossiers en cas de récursivité). setRecursivity(), setDeepRecursivity() et setProtected() sont des accesseurs qui permettent de modifier le statut des options de récursivité et de protection de tous les dossiers existants et de définir une option par défaut pour les ajouts futurs. Par défaut, la récursivité est permise sans limite de niveau (m_deepRecursivity vaut 0) et le contenu des dossiers n'est pas protégé (l'algorithme ne conservera qu'une copie des doublons, les autres fichiers étant supprimés ou déplacés selon les options du scan). listing() renvoie une liste de string représentant les chemins absolus des dossiers à scanner (permet d'informer l'utilisateur). */ #include <include/Directory.h> #include <string> using namespace std; class DirsToScan { public: DirsToScan(); void addDir(const string &absolutPath); void addDir(const string &absolutPath, const bool &protectedStatus, const bool &recursivity, const unsigned int &deepRecursivity); void delDir(const string &absolutPath); void setRecursivity(const bool &recursivity); void setDeepRecursivity(const unsigned int &deepRecursivity); void setProtected(const bool &protectedStatus); list<string> listing(); private: vector<*Directory> m_dirsToScan; bool m_recursivity = true; unsigned int m_deepRecursivity = 0; bool m_protectedStatus = false; }; #endif // DIRSTOSCAN_H
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 #ifndef DIRECTORY_H #define DIRECTORY_H /* La classe Directory représente un dossier à scanner. - m_absolutPath : string représentant le chemin absolu du dossier - 3 autres attribut privés possédant un accesseur SetAttribut() (sans le m_) : . bool m_recursivity : true / false : récursivité autorisée / interdite . unsigned int m_deepRecursivity : profondeur de la récursivité (0 = infini) . bool m_protectedStatus : si true, déclare le dossier comme protégé (pas d'effacement/déplacement de fichiers doubons dans ce dossier et ses sous- dossiers éventuels). - explore() : va explorer le dossier et ses sous-dossiers éventuels pour lister les fichiers et renvoyer le résultat sous forme de chemins absolus dans une list<string>. Cette fonction sera appelée par le constructeur et par setRecursivity() et setDeepRecursivity() s'ils modifient la valeur existante. Cette fonction prendrait tout son intérêt dans le cadre d'un multi-threading, permettant un pré-traitement des données au moment de la sélection des dossiers et avant le lancement d'un scan. */ using namespace std; class Directory { public: Directory(const string &absolutPath, const bool &protectedStatus, const bool &recursivity, const unsigned int &deepRecursivity); setRecursivity(const bool &recursivity); setDeepRecursivity(const unsigned int &deepRecursivity); setProtectedStatus(const bool &protectedStatus); private: list<string> explore(); string m_absolutPath; bool m_recursivity; unsigned int m_deepRecursivity; bool m_protectedStatus; }; #endif // DIRECTORY_H
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 #ifndef SCAN_H #define SCAN_H #include <include/DirsToScan.h> /* La classe Scan contient la procédure de scan et ses paramètres. ** Méthodes publiques : ** - int loadProfile() : charge un profile de paramètres inscrit dans un fichier dont on donne le chemin absolu. Renvoie un code différent de 0 en cas d'erreur. - int exec() : lance le scan avec les paramètres en vigueur stockés dans des attributs privés de la classe. - setNomDuParametre(T ¶metre) : accesseurs à définir pour la modification des paramètres du scan. */ using namespace std; class Scan { public: Scan(DirsToScan &directories); int loadProfile(string &profile); int exec(); void setNomDuParametre(T ¶metre); private: /* paramètres à définir (certains par enumérations ?) - filtres d'exclusion : fichiers cachés, fichiers système (.dll) et extensions diverses, taille mini/maxi, etc... - filtres d'inclusion : par extension */ }; #endif // SCAN_HQuestions :
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 #ifndef PROFILE_H #define PROFILE_H /* La classe DirsToScan représente un ensemble de dossiers à scanner. Chaque dossier à scanner est représenté par la classe Directory. Dans la classe, les objets de type Directory sont pointés dans un vector. ** Méthodes publiques : ** - load() et save() permettent respectivement de charger et sauvegarder un profile dans un fichier. Le path absolu du fichier est passé en paramètre sous forme d'une string. Le renvoie d'un code différent de 0 signale une erreur. Un fichier XML serait adapté : à voir pour comment le manipuler... Contiendrait les balises <absolutPath> <protected> <recursivity> <deepRecursivity> pour la partie <Directory>, <protected> <recursivity> <deepRecursivity> pour la partie <DirsToScan>, et les paramètres de scan dans la partie <Scan>. */ using namespace std; class Profile { public: Profile(DirsToScan &dirsToScan, Directory &directory, Scan &scan); int load(string &absolutPath); int save(string &absolutPath); private: }; #endif // PROFILE_H
1/ Cette structure des données vous parait-elle viable ? En particulier, faut ils intégrer les données des Directory directement dans DirsToScan ? C'est ce que j'aurai été tenté de faire, mais y a t'il un conteneur du style vector<typeDeDonnées1, typeDeDonnées2, typeDeDonnées3, typeDeDonnées4> qui me simplifierai les choses, à la manière d'un QAbstractItemModel de Qt ?
2/ Quelles sont les classes permettant de naviguer dans une arborescence de dossiers et de lister des fichiers d'un répertoire ?
3/ Pour manipuler les fichier XML (partie profile), une lib externe comme TinyXML est-elle nécessaire ? y a t'il un moyen plus simple de faire (simple fichier texte avec des mots clés à la place des balises, et on sait que aux lignes suivantes ont trouve le bloc de données que l'on cherche ?
Merci d'avance pour votre aide et toute remarque utile sur mon code ou autre![]()
Partager