Leçons du module (3/5)
io et os : fichiers et flux
La lecture et l'écriture de fichiers et de flux dans Go s'articulent autour de deux packages complémentaires : os (ouverture, création, métadonnées, processus) et io (les interfaces Reader/Writer qui extraient toute source d'octets).
Lire et écrire des fichiers : les raccourcis
Pour les petits fichiers ou les fichiers de configuration, un seul appel suffit :
data, err := os.ReadFile("input.txt") // returns []byte
if err != nil {
return err
}
fmt.Println(string(data))
err = os.WriteFile("out.txt", []byte("ciao"), 0644)os.ReadFile s'ouvre, lit tout en mémoire et se ferme. Parfait jusqu'à quelques Mo ; au-delà, le streaming est meilleur.
Ouverture de fichiers pour le streaming
Pour les fichiers volumineux ou un accès incrémentiel, ouvrez le fichier et fermez-le avec defer :
f, err := os.Open("big.txt") // read-only
if err != nil {
return err
}
defer f.Close()
buf := make([]byte, 4096)
for {
n, err := f.Read(buf)
if n > 0 {
process(buf[:n])
}
if err == io.EOF {
break
}
if err != nil {
return err
}
}os.Open s'ouvre en lecture seule. Pour écrire, utilisez os.Create (tronqué s'il existe) ou os.OpenFile(path, flag, perm) avec des indicateurs comme os.O_APPEND | os.O_CREATE | os.O_WRONLY.
io.Reader et io.Writer : les interfaces universelles
type Reader interface { Read(p []byte) (n int, err error) }
type Writer interface { Write(p []byte) (n int, err error) }Partout où la bibliothèque standard accepte un io.Reader vous pouvez passer un fichier (*os.File), une chaîne (strings.NewReader), un *bytes.Buffer, une réponse HTTP (resp.Body), un décompresseur... Il en va de même pour io.Writer.
// Copy from a Reader to a Writer (e.g. download → file).
n, err := io.Copy(dst, src)io.Copy est le cheval de bataille pour les pipelines d'octets : il gère correctement la mise en mémoire tampon et l'EOF. io.ReadAll(r) lit tout jusqu'à EOF dans un []byte.
os.Args : arguments CLI
os.Args est une tranche de chaînes : l'index 0 est le nom du programme, à partir de 1 sur les arguments réels :
func main() {
if len(os.Args) < 2 {
fmt.Fprintln(os.Stderr, "uso: prog <nome>")
os.Exit(1)
}
fmt.Println("ciao", os.Args[1])
}Pour une analyse plus structurée (drapeaux, valeurs par défaut, aide), utilisez le package flag de stdlib ou des bibliothèques externes comme cobra.
os.Stdin, os.Stdout, os.Stderr
Il s'agit de trois *os.File globaux : partout où un io.Reader ou un io.Writer est accepté, vous pouvez les transmettre.
fmt.Fprintln(os.Stderr, "log diagnostico")
io.Copy(os.Stdout, os.Stdin) // echoExercices
Imprimez le premier argument de ligne de commande (os.Args[1]). S'il manque, imprimez 'manca argomento' et retournez-le.
Solution disponible après 3 tentatives
Écrivez la chaîne 'ciao' dans le fichier 'out.txt' avec os.WriteFile (autorisations 0644). Gérez l'erreur.
Solution disponible après 3 tentatives
Quel est l'index du NOM DU PROGRAMME dans os.Args ?
fmt.Println(os.Args[???])