1. Principes de base de la bibliothèque OS

Le package os en Golang fournit une interface indépendante de la plate-forme pour les fonctions du système d'exploitation. Ensuite, nous discuterons de l'utilisation du package os pour gérer l'ouverture, la fermeture, la lecture, l'écriture de fichiers, ainsi que l'obtention et le réglage des attributs des fichiers.

1.1 Ouverture et fermeture de fichiers

En langage Go, vous pouvez utiliser la fonction os.Open pour ouvrir un fichier, qui renverra un objet *os.File et une erreur. Une fois le fichier ouvert, vous pouvez effectuer des opérations de lecture, d'écriture, et autres. Après l'exécution des opérations, vous devriez appeler file.Close pour fermer le fichier et libérer les ressources correspondantes.

Voici un exemple d'ouverture de fichier :

package main

import (
    "fmt"
    "os"
)

func main() {
    // Ouvrir le fichier test.txt dans le répertoire courant
    file, err := os.Open("test.txt")
    if err != nil {
        // Gérer l'erreur d'ouverture du fichier
        fmt.Println("Erreur à l'ouverture du fichier :", err)
        return
    }
    // Utiliser l'instruction defer pour assurer que le fichier est finalement fermé
    defer file.Close()

    // Opérations de manipulation de fichier...

    fmt.Println("Fichier ouvert avec succès")
}

Dans le code ci-dessus, nous utilisons l'instruction defer pour garantir que file.Close sera exécuté quoi qu'il arrive. Il s'agit d'une pratique courante en langage Go pour le nettoyage des ressources.

1.2 Opérations de lecture et d'écriture de fichiers

Le type os.File a des méthodes Read et Write, qui peuvent être utilisées pour les opérations de lecture et d'écriture de fichiers. La méthode Read lit les données du fichier dans une tranche de bytes, et la méthode Write écrit les données d'une tranche de bytes dans le fichier.

L'exemple suivant montre comment lire depuis et écrire dans un fichier :

package main

import (
    "fmt"
    "os"
)

func main() {
    // Ouvrir le fichier
    file, err := os.OpenFile("test.txt", os.O_RDWR, 0644)
    if err != nil {
        fmt.Println("Erreur à l'ouverture du fichier :", err)
        return
    }
    defer file.Close()

    // Écrire le contenu du fichier
    message := []byte("Salut, les Gophers !")
    _, writeErr := file.Write(message)
    if writeErr != nil {
        fmt.Println("Erreur d'écriture dans le fichier :", writeErr)
        return
    }

    // Lire le fichier depuis le début
    file.Seek(0, 0)
    buffer := make([]byte, len(message))
    _, readErr := file.Read(buffer)
    if readErr != nil {
        fmt.Println("Erreur de lecture du fichier :", readErr)
        return
    }

    fmt.Println("Contenu du fichier :", string(buffer))
}

Dans cet exemple, nous utilisons os.OpenFile au lieu de os.Open. La fonction os.OpenFile vous permet de spécifier le mode et les permissions à utiliser lors de l'ouverture du fichier. Dans l'exemple ci-dessus, le drapeau os.O_RDWR est utilisé, ce qui signifie que le fichier sera ouvert en mode lecture-écriture.

1.3 Propriétés de fichier et autorisations

Vous pouvez utiliser les fonctions du package os pour accéder et modifier les informations d'état des fichiers. Utilisez os.Stat ou os.Lstat pour obtenir l'interface os.FileInfo, qui fournit des informations sur le fichier telles que sa taille, ses autorisations, l'heure de modification, et plus encore.

Voici un exemple de comment obtenir les informations d'état d'un fichier :

package main

import (
    "fmt"
    "os"
)

func main() {
    fileInfo, err := os.Stat("test.txt")
    if err != nil {
        fmt.Println("Erreur lors de l'obtention des informations sur le fichier :", err)
        return
    }

    // Imprimer la taille du fichier
    fmt.Printf("Taille du fichier : %d octets\n", fileInfo.Size())

    // Imprimer les autorisations du fichier
    fmt.Printf("Autorisations du fichier : %s\n", fileInfo.Mode())
}

Si vous avez besoin de changer le nom du fichier ou modifier les autorisations du fichier, vous pouvez utiliser os.Rename pour renommer le fichier ou os.Chmod pour changer les autorisations du fichier.

package main

import (
    "fmt"
    "os"
)

func main() {
    // Changer les autorisations du fichier en lecture seule
    err := os.Chmod("test.txt", 0444)
    if err != nil {
        fmt.Println("Erreur lors du changement des autorisations du fichier :", err)
        return
    }

    // Renommer le fichier
    renameErr := os.Rename("test.txt", "renamed.txt")
    if renameErr != nil {
        fmt.Println("Erreur lors du renommage du fichier :", renameErr)
        return
    }

    fmt.Println("Opérations sur les fichiers réussies")
}

Ici, nous changeons les autorisations du fichier test.txt en lecture seule, puis renommons le fichier en renamed.txt. Notez que lors de la modification des autorisations de fichier, soyez prudent, car des paramètres d'autorisations incorrects peuvent rendre les fichiers inaccessibles.

2. Utilisation de base de la bibliothèque IO

En langage Go, la bibliothèque io fournit des interfaces de base pour les opérations d'E/S (entrée/sortie). La conception de la bibliothèque io suit les principes de simplicité et d'interfaces uniformes, fournissant un support de base pour différents types d'opérations d'E/S telles que la lecture/écriture de fichiers, la communication réseau, la mise en mémoire tampon de données, et plus encore.

2.2 Utilisation des interfaces Reader et Writer

io.Reader et io.Writer sont deux interfaces de base utilisées pour spécifier les opérations de lecture et d'écriture d'un objet. Elles sont implémentées par différents types tels que des fichiers, des connexions réseau et des tampons.

io.Reader

L'interface io.Reader a une méthode Read :

Read(p []byte) (n int, err error)

Cette méthode lit jusqu'à len(p) octets de données depuis l'io.Reader dans p. Elle renvoie le nombre d'octets lus n (0 <= n <= len(p)) et toute erreur rencontrée.

Exemple de code :

package main

import (
    "fmt"
    "io"
    "strings"
)

func main() {
    r := strings.NewReader("Bonjour tout le monde!")

    buf := make([]byte, 4)
    for {
        n, err := r.Read(buf)
        if err == io.EOF {
            break
        }
        fmt.Printf("Octets lus : %d, Contenu : %s\n", n, buf[:n])
    }
}

Dans cet exemple, nous créons un strings.NewReader pour lire des données depuis une chaîne et ensuite nous lisons les données par tranches de 4 octets.

io.Writer

L'interface io.Writer a une méthode Write :

Write(p []byte) (n int, err error)

Cette méthode écrit les données de p dans le flux de données sous-jacent, en renvoyant le nombre d'octets écrits et toute erreur rencontrée.

Exemple de code :

package main

import (
    "fmt"
    "os"
)

func main() {
    data := []byte("Bonjour tout le monde!\n")
    n, err := os.Stdout.Write(data)
    if err != nil {
        panic(err)
    }
    fmt.Printf("Octets écrits : %d\n", n)
}

Cet exemple écrit une simple chaîne sur la sortie standard os.Stdout, qui agit comme une implémentation de io.Writer.

2.3 Fonctions de lecture/écriture avancées

Le package io propose des fonctions avancées permettant de simplifier des tâches courantes, telles que la copie de données et la lecture d'une quantité précise de données.

Fonction de copie

La méthode io.Copy permet de copier directement des données depuis un io.Reader vers un io.Writer sans nécessiter de tampon intermédiaire.

Exemple de code :

package main

import (
    "io"
    "os"
    "strings"
)

func main() {
    r := strings.NewReader("Exemple d'opération de copie simple")
    _, err := io.Copy(os.Stdout, r)
    if err != nil {
        panic(err)
    }
}

Dans cet exemple, nous copions directement une chaîne vers la sortie standard.

Fonction ReadAtLeast

La fonction io.ReadAtLeast est utilisée pour garantir qu'au moins une quantité spécifiée de données est lue à partir d'un io.Reader avant de retourner.

func ReadAtLeast(r Reader, buf []byte, min int) (n int, err error)

Exemple de code :

package main

import (
    "fmt"
    "io"
    "strings"
)

func main() {
    r := strings.NewReader("Site Web en langue Go Chinoise")
    buf := make([]byte, 14)
    n, err := io.ReadAtLeast(r, buf, 14)
    if err != nil {
        fmt.Println(err)
    }
    fmt.Printf("%s\n", buf[:n])
}

Dans cet exemple, io.ReadAtLeast tente de lire au moins 14 octets de données dans buf.

Ces fonctions avancées de lecture/écriture vous permettent de gérer les tâches liées à l'E/S de manière plus efficace et fournissent une base solide pour construire une logique de programme plus complexe.