Help Instance Help

Section 1 : Lire le contenu d'un fichier

La façon la plus simple, mais pas nécessairement la plus efficace, de lire le contenu d'un fichier est d'utiliser la fonction os.ReadFile. Cette fonction ouvre le fichier, lit son contenu dans une chaîne de caractères, ferme le fichier, et retourne le contenu. Si le fichier est gros, les performances ne seront pas très bonnes parce que tout le fichier sera lu et placé dans une seule chaîne.

Exemple simple avec os.ReadFile

package main import ( "fmt" "os" "log" ) func section1a() { content, err := os.ReadFile("allo.txt") // Lecture du contenu du fichier if err != nil { log.Fatalf("lecture du contenu du fichier impossible : %s", err) } fmt.Println("Contenu du fichier :") fmt.Println(string(content)) }

Si le fichier existe, la sortie sera Contenu du fichier : sur la première ligne, suivi du contenu du fichier sur les lignes suivantes.

Si le fichier n'existe pas, alors il y aura une erreur, err ne sera pas nil, et le message d'erreur lecture du contenu du fichier impossible : sera affiché précédé de la date et l'heure, et suivi de l'erreur elle-même. La date et l'heure viennent de la fonction log.Fatalf, qui ajoute ces informations automatiquement. Aussi, cette fonction mettra un terme à l'exécution du programme parce qu'on utilise le niveau de log Fatal, qui veut dire qu'on ne peut pas continuer. Le f à la fin de la fonction est similaire au f à la fin de fmt.Printf, ce qui veut dire que la fonction accepte les formats pour la sortie.

Voir la doc officielle pour plus de détails sur le paquet log.

L'erreur la plus commune sera une erreur d'ouverture du fichier, similaire à open allo.txt: no such file or directory. Il faut en général que le fichier soit dans le même dossier que le programme compilé en fichier exécutable (extension .exe sous Windows) si on spécifie seulement le nom du fichier à ouvrir sans spécifier de chemin. On peut également spécifier un chemin relatif ou absolu avec un ou plusieurs dossiers séparés par des barres obliques. Le chemin relatif sera à partir du dossier où on exécute le programme.

Si on exécute le programme à travers l'interface graphique de GoLand, ça pourrait être différent, dépendamment de sa configuration. Normalement, le fichier .go sera compilé dans un dossier temporaire, et exécuté à partir du dossier du principal du projet. Donc le programme essaiera d'ouvrir un fichier à partir de ce dossier (à moins d'avoir spécifié un chemin absolu).

À partir d'un terminal, on peut compiler le programme à partir du dossier contenant le fichier .go avec go build, et exécuter le programme dans le terminal avec une commande du genre ./main.exe. Dans ce cas, l'ouverture d'un fichier se fera relativement au dossier courant.

Même exemple, mais avec ouverture et fermeture de fichier explicites

func section1b() { file, err := os.Open("allo.txt") // Ouverture du fichier en mode lecture if err != nil { log.Fatalf("ouverture du fichier impossible : %s", err) } content, err := io.ReadAll(file) // Lecture du contenu du fichier if err != nil { log.Fatalf("lecture du contenu du fichier impossible : %s", err) } fmt.Println("Contenu du fichier :") fmt.Println(string(content)) err = file.Close() if err != nil { log.Printf("erreur lors de la fermeture du fichier : %s", err) } }

Cet exemple a le même problème que le précédent si le fichier lu est gros. Le but ici est démontrer comment on peut ouvrir et fermer un fichier explicitement. Il existe une autre façon de fermer un fichier en Go, avec l'utilisation de defer, mais pour l'instant, nous le faisons de la manière longue.

  1. La fonction commence par ouvrir le fichier allo.txt en mode lecture avec os.Open. Si une erreur se produit (par exemple, si le fichier ne peut pas être trouvé), un message d'erreur sera affiché et le programme s'arrêtera avec log.Fatalf.

  2. Ensuite, la fonction lit le contenu du fichier avec io.ReadAll. Encore une fois, si une erreur se produit pendant la lecture (par exemple, si les données ne peuvent pas être interprétées correctement), un message d'erreur sera affiché et le programme s'arrêtera.

  3. Le contenu du fichier (qui est maintenant en mémoire sous forme de tableau de bytes) est converti en chaîne de caractères avec string(content) et est ensuite affiché dans la console avec fmt.Println.

  4. Enfin, la fonction essaie de fermer le fichier avec file.Close(). Si une erreur se produit lors de la fermeture du fichier (ce qui est rare, mais peut arriver si par exemple l'espace disque est plein et que le système ne peut pas mettre à jour les métadonnées du fichier), un message d'erreur sera affiché, mais contrairement aux erreurs précédentes, le programme ne s'arrêtera pas dans ce cas.

Exemple : Compter le nombre de lignes non-vides dans un fichier

Voici une fonction qui accepte le nom d'un fichier en paramètre, et qui compte le nombre de lignes non-vides dans ce fichier. Le nom de fichier peut inclure un chemin relatif ou absolu.

func countNonEmptyLines(filename string) { file, err := os.Open(filename) // Ouverture du fichier en mode lecture if err != nil { log.Fatalf("ouverture du fichier impossible : %s", err) } count := 0 scanner := bufio.NewScanner(file) for scanner.Scan() { if len(scanner.Text()) > 0 { count++ } } err = scanner.Err() if err != nil { log.Printf("erreur lors de la lecture du fichier : %s", err) } fmt.Println("Nombre de ligne non-vide :", count) err = file.Close() if err != nil { log.Printf("erreur lors de la fermeture du fichier : %s", err) } }
  1. La fonction countNonEmptyLines est définie, qui prend un nom de fichier en paramètre.

  2. La fonction essaie d'abord d'ouvrir le fichier en lecture. S'il y a une erreur (comme le fichier n'existe pas ou manque les permissions nécessaires), l'erreur est enregistrée et l'exécution du programme se termine.

  3. Une instance de bufio.Scanner, scanner pour le fichier ouvert est créée pour lire le fichier.

  4. Le fichier est lu ligne par ligne avec une boucle for. Si une ligne n'est pas vide (elle contient des caractères), le compteur est incrémenté.

  5. Après que les lignes ont été analysées, il vérifie s'il y a des erreurs qui se sont produites lors de la lecture du fichier. Si une erreur s'est produite, elle enregistre le message d'erreur.

  6. Le nombre de lignes non vides trouvées dans le fichier est imprimé.

  7. Enfin, le fichier est fermé et s'il y a une erreur lors de la fermeture du fichier, il enregistre le message d'erreur.

Last modified: 29 avril 2024