Pourquoi travailler avec les fichiers en Go n'est pas effrayant, mais intéressant ?
\n\nLorsque j'ai ouvert pour la première fois la documentation du package os en Go, j'ai pensé que j'allais trouver une énumération ennuyeuse d'appels système. Mais en creusant plus profondément, j'ai compris : travailler avec les fichiers et le système de fichiers en Go n'est pas seulement une question de lecture d'octets. C'est un outil puissant qui vous donne un contrôle total sur les données, qu'il s'agisse de fichiers de configuration, de journaux, de binaires ou de bases de données entières en CSV.
Go a été créé pour la programmation système, donc ses auteurs (Ken Thompson, Rob Pike et d'autres) ont intégré le travail avec les fichiers directement dans le noyau du langage. Aucune dépendance externe, seulement la bibliothèque standard, qui fonctionne rapidement et de manière prévisible. Dans cet article, nous allons couvrir tous les scénarios : de la simple lecture d'un fichier au parcours récursif de répertoires et au traitement en flux de grandes données.
\n\nSi vous écrivez en Go et que vous voulez travailler en toute confiance avec le système de fichiers, vous êtes au bon endroit. C'est parti !
\n\nLes bases : ouvrir, lire, fermer
\n\nLa toute première étape est l'ouverture d'un fichier. En Go, c'est la fonction os.Open() qui s'en charge. Elle retourne un pointeur vers le fichier et une erreur. Les erreurs en Go ne sont pas des exceptions, mais des valeurs. Il faut toujours les vérifier.
package main\n\nimport (\n "fmt"\n "os"\n)\n\nfunc main() {\n file, err := os.Open("example.txt")\n if err != nil {\n fmt.Println("Erreur d'ouverture du fichier :", err)\n return\n }\n defer file.Close() // fermer le fichier obligatoirement\n\n // Lire le contenu\n buf := make([]byte, 1024)\n n, err := file.Read(buf)\n if err != nil {\n fmt.Println("Erreur de lecture :", err)\n return\n }\n fmt.Printf("Lu %d octets : %s\\n", n, string(buf[:n]))\n}\n\n\nNotez l'utilisation de defer file.Close(). C'est un idiome de Go : l'appel différé garantit que le fichier sera fermé même en cas de panique ou de retour anticipé. Oublier de fermer un fichier est une mauvaise pratique qui entraîne une fuite de descripteurs.
Lire tout un fichier en une seule ligne
\n\nSi le fichier est petit (jusqu'à quelques mégaoctets), vous pouvez utiliser os.ReadFile() (qui a remplacé l'ancien ioutil.ReadFile). C'est pratique pour les fichiers de configuration ou les données textuelles.
data, err := os.ReadFile("config.yaml")\nif err != nil {\n log.Fatal(err)\n}\nfmt.Println(string(data))\n\n\nLa fonction ouvre, lit et ferme le fichier elle-même. Mais rappelez-vous : pour les gros fichiers, cette approche est dangereuse - vous chargerez tout le fichier en mémoire.
\n\nÉcrire dans un fichier : créer et ajouter
\n\nPour écrire, utilisez os.Create() (crée un nouveau fichier ou tronque un fichier existant) et os.OpenFile() pour un réglage plus fin (par exemple, ajout à la fin).
// Création d'un fichier\nfile, err := os.Create("output.txt")\nif err != nil {\n panic(err)\n}\ndefer file.Close()\n\n// Écrire une chaîne\n_, err = file.WriteString("Bonjour, fichiers Go !\\n")\nif err != nil {\n panic(err)\n}\n\n// Écrire des octets\nbytes := []byte("Écriture d'une tranche d'octets\\n")\n_, err = file.Write(bytes)\nif err != nil {\n panic(err)\n}\n\n\nPour ajouter des données à la fin d'un fichier existant, utilisez les drapeaux :
\n\nfile, err := os.OpenFile("log.txt", os.O_APPEND|os.O_CREATE|os.O_WRONLY, 0644)\nif err != nil {\n log.Fatal(err)\n}\ndefer file.Close()\n\nfile.WriteString("Nouvelle entrée dans le journal\\n")\n\n\nLe drapeau os.O_APPEND garantit que les données seront ajoutées à la fin, et non écrasées au début.
Travailler avec les répertoires : créer, supprimer, parcourir
\n\nLe système de fichiers ne comprend pas seulement des fichiers, mais aussi des dossiers. Go fournit des fonctions pratiques pour travailler avec les répertoires.
\n\nCréation et suppression de dossiers
\n\n// Créer un seul dossier\nerr := os.Mkdir("newdir", 0755)\nif err != nil {\n log.Fatal(err)\n}\n\n// Créer des dossiers imbriqués (comme mkdir -p)\nerr = os.MkdirAll("path/to/nested/dir", 0755)\nif err != nil {\n log.Fatal(err)\