Aller au menu - Aller au contenu

Icône Les fichiers - Partie 2/2

Avatar
Mise à jour : 13/12/2010
Difficulté : Facile Facile Creative Commons BY-NC-SA
23 410 visites depuis 7 jours, dont 274 sur ce chapitre classé 14/786
La suite sur les fichiers :

Des notions supplémentaires qui peuvent être utiles.

Mais attention, le niveau monte d'un cran, accrochez-vous !
Sommaire du chapitre :
Icône du chapitre
Chapitre précédent Sommaire Chapitre suivant

Plus loin avec nos fichiers

Allez, continuons donc sur notre lancée. Voyons les fonctions spécifiques aux fichiers plus en détail.

Tout d'abord la technique que je vous ai montrée utilise le principe du Stream. Autrement dit : Flux.
Dans le principe : le fichier est intégralement ouvert et inséré dans un objet de type Stream. Pendant le temps que le stream est ouvert (fichier ouvert par le programme), son écriture par une autre instance (un autre programme) est impossible.

Cette technique comporte des avantages et des inconvénients : on peut être certain que le fichier ne sera pas modifié pendant le déroulement du programme, mais par contre, il est bloqué et donc plusieurs programmes ne peuvent pas travailler dessus en même temps.

Bref, je parie que vous voulez une autre technique.

La classe File vient à votre secours !

La classe File



Cette classe est pré-implémentée dans le Framework. On va créer le même programme de lecture / écriture avec cette classe.

Image utilisateur


La même interface donc, le code va légèrement changer :

Code : VB.NET
 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
Imports System.IO

Public Class Form1

    Const PATHFICHIER As String = "Zero.txt"    

    Private Sub BT_CLEARLIRE_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles BT_CLEARLIRE.Click
        Me.TXT_LECTURE.Text = ""
    End Sub

    Private Sub BT_CLEARECRIRE_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles BT_CLEARECRIRE.Click
        Me.TXT_ECRITURE.Text = ""
    End Sub

    Private Sub BT_CLEAR_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles BT_CLEAR.Click
        File.WriteAllText(PATHFICHIER , "")
    End Sub

    Private Sub BT_LIRE_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles BT_LIRE.Click
        Me.TXT_LECTURE.Text = File.ReadAllText(PATHFICHIER )
    End Sub

    Private Sub BT_ECRIRE_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles BT_ECRIRE.Click
        If Me.CHK_DEBUT.Checked Then
	    'Depuis le début
            File.WriteAllText(PATHFICHIER , Me.TXT_ECRITURE.Text)
        Else
	    'A la suite
            File.AppendAllText(PATHFICHIER , Me.TXT_ECRITURE.Text)
        End If

    End Sub
End Class


Il n'y a plus rien !?!

Eh bien oui, si on veut. La classe File a les outils nécessaires pour effectuer les actions que nous avions besoin.

Mais tu es stupide ! Pourquoi tu nous as ennuyé avec tes 500 lignes au chapitre précédent ?

Eh bien, je vous aurais montré qu'on aurait pu le faire ainsi, vous auriez réellement pris le temps de comprendre tout ce qui a été introduit au chapitre précédent ? (Les objets, le stream, les conversions de caractères).

Bon, cette classe nous permet de lire / écrire rapidement dans nos fichiers. Examinons quand même ces lignes.

Tout d'abord une variable constante de déclarée pour spécifier le Path que je vais utiliser pendant tout le programme : Const PATHFICHIER As String = "Zero.txt" . Path relatif bien évidemment.

File.WriteAllText(PATHFICHIER , Me.TXT_ECRITURE.Text) : La méthode WriteAllText de la classe File permet d'écrire du texte dans un fichier en redémarrant du début. Donc effacement du contenu précédent (ce que j'ai utilisé pour l'effacement du fichier).


File.AppendAllText(PATHFICHIER , Me.TXT_ECRITURE.Text) : LA méthode AppendAllText quant à elle écrit à la suite du fichier, donc je l'ai utilisé lorsque la checkbox est cochée.

Il nous reste finalement la lecture : Me.TXT_LECTURE.Text = File.ReadAllText(PATHFICHIER ) . Une fonction cette fois-ci qui lit depuis le début et entre le tout dans un string. String que j'affiche directement via ma textbox.

Quelle simplification quand même, je vous rassure, par la suite nous utiliserons cette classe, nous nous concentrerons plus sur le fonctionnel des fichiers que sur comment effectuer nos manipulations dessus.

Découvrons d'autres manipulations



Bien, tout d'abord le légendaire move, autrement dit déplacement du fichier.

Code : VB.NET
1
File.Move(Source as string, Destination as string)


Vous pouvez bien évidemment utiliser des chemins relatifs / absolus ou mélanger les deux =).
Cette méthode est également utilisée pour renommer les fichiers, il suffit simplement d'effectuer le move avec deux noms différents, mais sur le même Path.


La copie :



Code : VB.NET
1
File.Copy(Source as string, Destination as string)


Même principe que la méthode précédente, vous n'avez cependant pas le droit d'attribuer le même nom à la source et à la destination.


La vérification de la présence du fichier :



Code : VB.NET
1
File.Exists(Fichier as string)


Fonction très importante ! Lorsque l'on va effectuer des manipulations, toujours vérifier la présence du fichier avant d'effectuer une action dessus ! Vous ne voulez pas vous retrouver avec une grosse erreur qui tache ! Renvoie une Boolean : True si présence du fichier, False dans le cas contraire.

Les répertoires

Bien, nous savons manipuler les fichiers assez bien je dois dire, du moins suffisamment pour les utilités que nous allons leur donner.

Attaquons alors maintenant les répertoires.

Bon, cette fois pas de stream ou autres, la classe Directory est la seule dans le namespace IO (Directory : répertoire).

Fonctions de modification



On va commencer par la fonction à utiliser avant toute chose :

La vérification :



Code : VB.NET
1
Directory.Exists(Path As String)


Renvoie un booléen encore une fois, bien évidemment très important ! On l'utilisera systématiquement !


La création de dossiers :



Code : VB.NET
1
Directory.CreateDirectory(Path As String)


Alors, cette méthode est assez magique. Elle va créer entièrement le Path spécifié. Je m'explique :
Parlons en path relatif : il n'y a actuellement aucun dossier dans le répertoire d'exécution de votre programme. Si en argument de la méthode je passe "Dossier1/SousDossier1/SousSousDossier1", il y aura 3 dossiers de créés, suivant l'arborescence définie :
Le dossier "Dossier1" sera créé directement dans le répertoire, le dossier "SousDossier1" sera crée dans "Dossier1" et finalement le dossier "SousSousDossier1" sera créé dans "SousDossier1". Le tout pour dire à quel point cette méthode peut se révéler pratique.


La suppression :



Code : VB.NET
1
Directory.Delete(Path As String, Recursif As Boolean)


Alors, ici nous avons un second argument en plus du path du dossier à supprimer ; il correspond à la récursivité. Si vous activez la récursivité, les dossiers et fichiers en "dessous" (dans l'arborescence des fichiers) du path que vous avez indiqués seront également supprimés, sinon si la récursivité n'est pas activée et que vous tentez de supprimer un dossier qui n'est pas vide, une erreur surviendra.
En résumé : la récursivité supprime le répertoire plus l'intégralité de son contenu !



Le légendaire Move :



Code : VB.NET
1
Directory.Move(PathSource As String, PathDest As String)


Même principe que pour les fichiers, avec les répertoires cette fois-ci : déplace le dossier et son contenu vers le nouveau Path.


Fonctions d'exploration



Bien, vous savez maintenant manipuler les fichiers ET les répertoires, mais il va falloir associer les deux pour pouvoir rendre vos programmes exportables et adaptables aux environnements.

Nous allons donc apprendre à chercher dans un dossier spécifié les sous-dossiers et les fichiers qu'il contient.
Bref, cela va nous permettre de pouvoir nous représenter notre arborescence. Nous allons également créer un petit programme permettant de représenter l'arborescence de notre disque.

Commençons donc avec les fonctions :

Rechercher tous les dossiers contenus dans le dossier spécifié :



Code : VB.NET
1
Directory.GetDirectories(Path as String)


Renvoie un tableau de string contenant le path de tous les dossiers qui sont contenus dans le dossier spécifié.
Cette fonction revoit un path absolu si vous lui en avez fourni un au départ, un path relatif dans le cas contraire. Attention de toujours utiliser le même type de Path !



Rechercher tous les fichiers contenus dans un dossier spécifié :



Code : VB.NET
1
Directory.GetFiles(Path as String)


Comme pour au-dessus, même remarque le path renvoyé correspond à celui que vous avez passé en argument. Renvoie les fichiers avec leur extension.

Un rapide bout de code permet de lister les fichiers présents en utilisant cette fonction :

Code : VB.NET
1
2
3
For Each Fichier As String In Directory.GetFiles("c:/")
            MsgBox(Fichier)
        Next


Eh bien voilà.

Mini-TP : Lister notre arborescence

Tout d'abord, explorons notre arborescence avec une commande tout faite dans notre invite de commande Windows.
La commande shell (commande spécifique à Windows) s'appelle Tree. Elle donne un résultat de ce genre :

Image utilisateur


Vous n'avez pas besoin d'utiliser cette commande c'est pour vous montrer l'arborescence du dossier dans lequel nous allons faire notre mini-tp.

Nous allons donc retrouver notre arborescence de manière a se retrouver avec le même schéma, le tout grâce a un algorithme.
Je vous ai déjà parlés du principe d'un algorithme. Eh bien nous allons devoir en trouver un pour pouvoir effectuer ce listage.
Nous récupérerons les informations et les afficherons dans un TreeView (ça vous donnera l'occasion de découvrir un nouveau contrôle), spécifiquement conçu pour effectuer des arborescences (avec des parents et des enfants).

Pour résumer, dans le TreeView : un dossier correspondra à un noeud principal (on peut cliquer dessus pour le "déplier") et un fichier sera un noeud simple, pas de possibilité de le "dérouler".

C'est un programme très basique, sa base pourra être utilisée dans d'autres programmes qui nécessitent une exploration des répertoires.

Donc passons à l'algorithme. Je ne suis pas là pour vous apprendre les rudiments et normes de l'algorithmie, j'aimerai juste un peu de logique de votre part, peu importe comment vous vous représentez ce qu'il va y avoir à faire (schéma, texte, dessin, ...).

Le tout est de comprendre ce qu'on va devoir effectuer comme action, appeler comme fonctions.

Un algorithme version texte tout simple :



Parcourir le répertoire, pour chaque dossier ajouter un noeud principal, pour chaque fichier ajouter un noeud simple.
Répéter cette action pour chaque répertoire

(Attention, cet algorithme ne respecte pas les normes de l'algorithme, si vous voulez en savoir plus, de très bon tutos existent sur le SDZ)

Maintenant il va falloir l'adapter pour le rentrer dans notre code.

Le code VB :



Code : VB.NET
 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
Imports System.IO

Public Class Form1

    Const RepertoireALister As String = "."

    Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
        'Définit le premier noeud
        Me.TV_ARBORESCENCE.TopNode = Me.TV_ARBORESCENCE.Nodes.Add(RepertoireALister, RepertoireALister)

        'Arborescence du premier noeud
        For Each Repertoire As String In Directory.GetDirectories(RepertoireALister)
            Me.TV_ARBORESCENCE.TopNode.Nodes.Add(Repertoire, Path.GetFileName(Repertoire))
            'Récursif
            ListeArborescenceDossier(Repertoire, Me.TV_ARBORESCENCE.TopNode)
        Next
        'Fichiers du premier noeud
        For Each Fichier As String In Directory.GetFiles(RepertoireALister)
            Me.TV_ARBORESCENCE.TopNode.Nodes.Add(Path.GetFileName(Fichier))
        Next
    End Sub

    Sub ListeArborescenceDossier(ByVal RepertoireActuel As String, ByVal NodeActuel As TreeNode)
        'Recupère le node dans lequel on est
        Dim Node As TreeNode = NodeActuel.Nodes(RepertoireActuel)
        'Répertoires de ce noeud
        For Each Repertoire As String In Directory.GetDirectories(RepertoireActuel)
            Node.Nodes.Add(Repertoire, Path.GetFileName(Repertoire))
            'Récursif
            ListeArborescenceDossier(Repertoire, Node)
        Next
        'Fichiers de ce noeud
        For Each Fichier As String In Directory.GetFiles(RepertoireActuel)
            Node.Nodes.Add(Path.GetFileName(Fichier))
        Next
    End Sub

End Class


Expliquons un peu le tout. Tout d'abord Node en anglais signifie Nœud.
Tout d'abord, le répertoire que je dois explorer en constante, vous pouviez bien évidemment créer une textbox demandant à l'utilisateur quel dossier lister. Le path que j'ai utilisé est "." cela signifie le dossier courant, c'est un Path Relatif.

Vient le load, je crée d'office un TopNode autrement dit "le nœud le plus haut", le nœud principal de notre treeview. J'en profite pour créer un noeud avec : Me.TV_ARBORESCENCE.Nodes.Add(). En premier argument de cette fonction la "clé" pour identifier le nœud dans le treeview, cette clé doit avoir un nom unique, et en second le texte qui sera affiché sur mon nœud.

Ensuite, la petite boucle que je vous ai montrée plus haut : je parcours tout les répertoires dans le répertoire à lister, je les ajoute en tant que nœud principal avec comme clé leur path entier (exemple : "./Dossier1/SousDossier1") donc un nom qui est unique, et en texte le nom du dossier simplement. Nom de dossier que j'ai récupéré en utilisant la classe Path qui donne des méthodes et fonction pour manipuler les chemins. J'ai utilisé la fonction GetFileName qui renvoie le nom du fichier ou le nom d'un dossier contenu dans un Path.

Puis j'appelle une méthode que je vous exposerai juste après.

Quand il n'y a plus de dossiers on passe aux fichiers, sur le même principe sauf que ces nœuds n'auront pas de nœud enfants. Donc pas dépliables.

La méthode que j'ai mise juste après, eh bien c'est elle qui va nous permettre d'effectuer la récursivité de notre algorithme à travers tous les sous dossiers.

Sans elle, on aurait seulement le niveau 0 de notre arborescence de listé (les dossiers et fichiers du répertoire principal) et pas plus loin.

Eh bien pour ce qui est de la fonction, elle effectue exactement la même chose que ce que je viens d'expliquer mais où le nom du répertoire et le nœud dans lequel on se trouve actuellement sont passés en paramètres de façon à permettre de la rappeler dynamiquement et pour qu'elle puisse s'adapter aux différents niveaux de l'arborescence.

Résultat :



Image utilisateur


Je tiens juste à vous dire que si vous prenez un peu de temps, essayez de comprendre le fonctionnement de ce programme étape par étape (commencez par un seul niveau d'arborescence), vous allez comprendre la démarche qu'il effectue et ce sera un premier et un grand pas vers de notions de programmation plus complexe que nous allons aborder dans la partie 3 de ce tutoriel.
Autre conseil pour vous éclairer le programme : créez des variables intermédiaires dans lesquelles vous vous habituerez à trouver le bon type de variable à employer, les méthodes disponibles sur ce type, pour finalement arriver à tout rassembler tout en le laissant clair à vos yeux.

Un fichier bien formaté

Bien, passons aux fichiers de configuration.

Peut-être que quelques-uns d'entre vous ont déjà vu les fichiers de configuration standard de Windows : les Fichiers .ini

Ces fichiers ont été utilisés par Windows pour définir les paramètres de configuration. C'est de simples fichiers contenant du texte mais au lieu d'avoir l'extension basique de texte : .txt, ils ont une extension .ini

Petite parenthèse sur les extensions : elles ne définissent pas obligatoirement le contenu du fichier, les fichiers .jpg contiennent habituellement des images et ont l'habitude d'être ouverts par des logiciels de dessin ou de visualisation d'image mais ils peuvent très bien contenir du texte et être ouvert avec le bloc-notes.

Les fichiers .ini contiennent donc du texte mais formaté d'une certaine manière, nous allons l'étudier ici.

Exemple de mon fichier Win.ini :



Code : Autre
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
; for 16-bit app support
[fonts]
[extensions]
[mci extensions]
[files]
[Mail]
MAPI=1
[MCI Extensions.BAK]
3g2=MPEGVideo
3gp=MPEGVideo
3gp2=MPEGVideo
3gpp=MPEGVideo
aac=MPEGVideo
adt=MPEGVideo
adts=MPEGVideo
m2t=MPEGVideo
m2ts=MPEGVideo
m2v=MPEGVideo
m4a=MPEGVideo
m4v=MPEGVideo
mod=MPEGVideo
mov=MPEGVideo
mp4=MPEGVideo
mp4v=MPEGVideo
mts=MPEGVideo
ts=MPEGVideo
tts=MPEGVideo


Explications :



Le contenu d'un fichier de configuration .ini contient 3 types de lignes :

  • Les lignes commençant par ";" sont des commentaires, elles ne sont pas prises en compte pendant le traitement du fichier.
  • Les lignes où il y a des crochets : "[" "]" définissent une nouvelle section. Cela permet d'organiser un minimum notre fichier .ini
  • Finalement les lignes de clé, les plus importantes, elles contiennent les variables que nous stockons. Par exemple "MAPI=1" signifie que la variable (ou clé) MAPI est égale à 1.


Bon, vous voyez maintenant le principe d'un fichier de configuration. A quoi diable va-t-il nous servir ? Eh bien simplement à garder des paramètres du programme même s'il y a eu un arrêt de ce dernier.

Bien, vous voilà donc avec une petite norme à respecter pour stocker vos informations de configuration (ça ne fait pas de mal de temps en temps).

Nous allons passer à un TP conséquent et qui va vous demander de réviser vos notions sur les fichiers. C'est juste après.

Q.C.M.

La méthode AppendAllText permet de faire quoi ?
Code : VB.NET
1
File.Exists()


Renvoie une variable de quel type ?
Code : VB.NET
1
Directory.GetFiles()


Renvoie quel type de variable ?

Statistiques de réponses au QCM

Chapitre précédent Sommaire Chapitre suivant

Partager

14 commentaires pour "Les fichiers - Partie 2/2"
Note moyenne : 3.60 / 4 (543 votes)
Pseudo Commentaire
Hors ligne Tsunamichups # Posté le 27/06/2011 à 23:30:49
Avatar

Avis : Décevant

J'ai exactementle meme probleme que ci dessus et pas de reponse pour contenter ma frustration

Le tuto est fait un peu a la va vite comme il a été dit plus haut
Dommage car les chapitre d'avant était parfait

J'ai apporté des modification au script de base mais rien y fait

Code : VB.NET
 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
Imports System.IO

Public Class Form1

    Dim repertoireALister = "."

    Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
        'Définit le premier noeud
        Me.Tv_arboressence.TopNode = Me.Tv_arboressence.Nodes.Add(repertoireALister, repertoireALister)

        'Arboressence du premier noeud
        For Each Repertoire As String In Directory.GetDirectories(repertoireALister)
            Me.Tv_arboressence.TopNode.Nodes.Add(repertoireALister, Path.GetFileName(Repertoire))

            'Fichier de ce noeud
            For Each Fichier As String In Directory.GetFiles(repertoireALister)
                Me.Tv_arboressence.TopNode.Nodes.Add(Path.GetFileName(Fichier))
            Next


            'Récursif
            listeArborescenceDossier(Repertoire, Me.Tv_arboressence.TopNode)
        Next

        
    End Sub

    Sub listeArborescenceDossier(ByVal RepertoireActuel As String, ByVal NodeActuel As TreeNode)
        'Récuperele node dans lequel on est
        Dim Node As TreeNode = NodeActuel.Nodes(RepertoireActuel)

        'Répertoire de ce noeud
        For Each Repertoire As String In Directory.GetDirectories(RepertoireActuel)
            Node.Nodes.Add(RepertoireActuel, Path.GetFileName(Repertoire))

            'Fichier de ce noeud
            For Each Fichier As String In Directory.GetFiles(RepertoireActuel)
                Node.Nodes.Add(Path.GetFileName(Fichier))
            Next

            'Récursif
            listeArborescenceDossier(Repertoire, Node)
        Next

       
    End Sub
End Class
Hors ligne Tsunamichups # Posté le 29/06/2011 à 09:19:19
Avatar

Avis : Décevant

Je viens de faire un copier coller, il semblerais que cela fonctionne finalement.
J'ai pourtant tester ce code en copier coller de chez moi mais il ne semblais pas que cela fonctionnais.

Est ce que la version de virtual 2010 peu influer sur le résultat du logicel ?
Hors ligne gillardj77 # Posté le 22/08/2011 à 16:08:15
Avatar

bonjour a tous j'aurais voulu savoir comment faire pour ecrir dans un fichier grace a une text box en faisent dans retour a la ligne a chaque fois qu'on ecrit quelque chose
pacque grace a " file.AppendAllText(...,...) " et bien sa ecrit sur la meme ligne donc voila
merci d'avence pour vos reponse
Hors ligne lomou23 # Posté le 28/10/2011 à 15:26:40
Avatar

Je ne comprends pas comment accéder au fichier .ini ...
Hors ligne Ma7hew # Posté le 19/11/2011 à 10:49:21
Avatar

Ville : Lille
Pays : France métropolitaine

Personnellement, je trouve que la partie sur les fichiers de configuration .ini n'est pas totalement exploitée (pour ne pas dire bâclée)...

Je suis conscient qu'il seront utilisés dans le TP suivant, et je pourrais je l'espère mieux comprendre, mais à ce stade, on sait juste leur organisation !

Comment les exploiter ? Dans quelle circonstance ? Comment les déclarer depuis VB ? Et surtout les importer ?

En espérant une mise à jour globale du tutoriel (à 40% depuis 2010) pour la clarté, et aussi introduire les notions supplémentaires promises.

Je félicite l'auteur pour son initiative, et l'invite toutefois à revenir sur certains points du tuto qui sont pour nombre d'entre nous (cf les commentaires) parfois trop vite expliqués ...
(On se souvient du manque par exemple d'explication quant à la liaison du menu contextuel à la fenêtre en cours, un grand merci à la communauté, car je me suis battu avec mon clic droit ^^)

Voir tous les commentaires