315 votes

Comment lire / écrire de / dans un fichier?

J'ai essayé d'apprendre Aller seul, mais j'ai été empêché d'essayer de lire et d'écrire dans des fichiers ordinaires.

Je peux aller aussi loin que inFile,_ := os.Open(INFILE,0,0); , mais obtenir le contenu du fichier n'a pas de sens, car la fonction de lecture prend un []byte comme paramètre.

 func (file *File) Read(b []byte) (n int, err Error)
 

526voto

Mostafa Points 7468

Nous allons faire un Aller de 1 compatible liste de toutes les manières de lire et d'écrire des fichiers en Aller.

Car le fichier API a changé récemment et la plupart des autres réponses ne fonctionnent pas avec Go 1. Ils ont également manquer bufio ce qui est important à mon humble avis.

Dans les exemples qui suivent, je copie un fichier en lecture et en écriture dans le fichier de destination.

Commencer avec les bases

package main

import (
    "io"
    "os"
)

func main() {
    // open input file
    fi, err := os.Open("input.txt")
    if err != nil { panic(err) }
    // close fi on exit and check for its returned error
    defer func() {
        if err := fi.Close(); err != nil {
            panic(err)
        }
    }()

    // open output file
    fo, err := os.Create("output.txt")
    if err != nil { panic(err) }
    // close fo on exit and check for its returned error
    defer func() {
        if err := fo.Close(); err != nil {
            panic(err)
        }
    }()

    // make a buffer to keep chunks that are read
    buf := make([]byte, 1024)
    for {
        // read a chunk
        n, err := fi.Read(buf)
        if err != nil && err != io.EOF { panic(err) }
        if n == 0 { break }

        // write a chunk
        if _, err := fo.Write(buf[:n]); err != nil {
            panic(err)
        }
    }
}

Ici, j'ai utilisé os.Open et os.Create qui sont commodes wrappers autour os.OpenFile. Habituellement, nous n'avez pas besoin d'appeler OpenFile directement.

Avis de traitement des expressions du FOLKLORE. Read tente de remplir buf sur chaque appel, et les retours io.EOF d'erreur si il arrive à la fin du fichier. Dans ce cas - buf conservent des données. Conséquente des appels d' Read renvoie zéro à mesure que le nombre d'octets lus et même io.EOF d'erreur. Toute autre erreur conduira à une panique.

À l'aide de bufio

package main

import (
    "bufio"
    "io"
    "os"
)

func main() {
    // open input file
    fi, err := os.Open("input.txt")
    if err != nil { panic(err) }
    // close fi on exit and check for its returned error
    defer func() {
        if err := fi.Close(); err != nil {
            panic(err)
        }
    }()
    // make a read buffer
    r := bufio.NewReader(fi)

    // open output file
    fo, err := os.Create("output.txt")
    if err != nil { panic(err) }
    // close fo on exit and check for its returned error
    defer func() {
        if err := fo.Close(); err != nil {
            panic(err)
        }
    }()
    // make a write buffer
    w := bufio.NewWriter(fo)

    // make a buffer to keep chunks that are read
    buf := make([]byte, 1024)
    for {
        // read a chunk
        n, err := r.Read(buf)
        if err != nil && err != io.EOF { panic(err) }
        if n == 0 { break }

        // write a chunk
        if _, err := w.Write(buf[:n]); err != nil {
            panic(err)
        }
    }

    if err = w.Flush(); err != nil { panic(err) }
}

bufio est tout simplement agir comme un tampon ici, parce que nous n'avons pas beaucoup à faire avec les données. Dans la plupart des autres situations (spécialement avec des fichiers de texte) bufio est très utile en nous donnant une bonne API pour la lecture et l'écriture de manière simple et flexible, alors qu'il gère de mise en mémoire tampon derrière les coulisses.

À l'aide de ioutil

package main

import (
    "io/ioutil"
)

func main() {
    // read whole the file
    b, err := ioutil.ReadFile("input.txt")
    if err != nil { panic(err) }

    // write whole the body
    err = ioutil.WriteFile("output.txt", b, 0644)
    if err != nil { panic(err) }
}

Facile comme bonjour! Mais ne l'utilisez que si vous êtes sûr que vous n'êtes pas affaire avec de gros fichiers.

53voto

Piotr Points 187

Il s’agit de la bonne version :

33voto

user7610 Points 820

À l’aide``

Si vous n’envie de réinventer la roue, le et peut bien vous servir. Si vous Vérifiez la source de l’io. Copiez la fonction, c’est rien d’autre qu’une des solutions de la Mostafa (celle « de base », en fait) emballés dans la bibliothèque de Go. Ils utilisent un tampon significativement plus gros que lui, cependant.

10voto

peterSO Points 25725

[]byte est une tranche (similaire à une sous-chaîne) de tout ou partie d'un tableau d'octets. Pensez à la tranche comme une structure de valeur avec une cachée du pointeur de champ pour le système de localiser et d'accéder à tout ou partie d'un tableau (la tranche), en plus des champs pour la longueur et la capacité de la tranche à laquelle vous pouvez accéder à l'aide de l' len() et cap() fonctions.

Voici un travail de kit de démarreur pour vous, qui lit et imprime un fichier binaire; vous aurez besoin de changer l' inName de la valeur littérale qui désigne un petit fichier sur votre système.

package main
import (
    "fmt";
    "os";
)
func main()
{
    inName := "file-rw.bin";
    inPerm :=  0666;
    inFile, inErr := os.Open(inName, os.O_RDONLY, inPerm);
    if inErr == nil {
    	inBufLen := 16;
    	inBuf := make([]byte, inBufLen);
    	n, inErr := inFile.Read(inBuf);
    	for inErr == nil {
    		fmt.Println(n, inBuf[0:n]);
    		n, inErr = inFile.Read(inBuf);
    	}
    }
    inErr = inFile.Close();
}

7voto

marketer Points 3938

Essayez ceci :

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X