Passer au contenu principal
eLearner.app
Module 8 · Leçon 3 sur 538/50 dans le cours~14 min
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 :

Go
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 :

Go
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

Go
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.

Go
// 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 :

Go
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.

Go
fmt.Fprintln(os.Stderr, "log diagnostico")
io.Copy(os.Stdout, os.Stdin)  // echo

Exercices

Exercice#go.m8.l3.e1
Tentatives : 0Chargement…

Imprimez le premier argument de ligne de commande (os.Args[1]). S'il manque, imprimez 'manca argomento' et retournez-le.

Chargement de l'éditeur…

Solution disponible après 3 tentatives

Exercice#go.m8.l3.e2
Tentatives : 0Chargement…

Écrivez la chaîne 'ciao' dans le fichier 'out.txt' avec os.WriteFile (autorisations 0644). Gérez l'erreur.

Chargement de l'éditeur…

Solution disponible après 3 tentatives

Quiz#go.m8.l3.e3
Prêt

Quel est l'index du NOM DU PROGRAMME dans os.Args ?

Go
fmt.Println(os.Args[???])
Options de réponse