Faisons une liste compatible Go 1 de toutes les façons de lire et d'écrire des fichiers dans Go.
Parce que l'API de fichiers a changé récemment et la plupart des autres réponses ne fonctionnent pas avec Go 1. Ils manquent également bufio
ce qui est important à mon humble avis.
Dans les exemples suivants, je copie un fichier en le lisant et en l'écrivant dans le fichier de destination.
Commencez 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 des emballages pratiques autour os.OpenFile
. Nous n'avons généralement pas besoin d'appeler OpenFile
directement.
Remarquez le traitement de l'EOF. Read
essaie de répondre buf
à chaque appel et retourne io.EOF
comme erreur s'il atteint la fin du fichier. Dans ce cas buf
, conservera toujours les données. Les appels ultérieurs à Read
renvoie zéro comme le nombre d'octets lus et identique io.EOF
à l'erreur. Toute autre erreur entraînera une panique.
En utilisant 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
agit simplement comme un tampon ici, car nous n'avons pas grand-chose à voir avec les données. Dans la plupart des autres situations (spécialement avec les fichiers texte), bufio
c'est très utile en nous donnant une belle API pour lire et écrire facilement et de manière flexible, tout en gérant la mise en mémoire tampon en arrière-plan.
En utilisant ioutil
package main
import (
"io/ioutil"
)
func main() {
// read the whole file at once
b, err := ioutil.ReadFile("input.txt")
if err != nil {
panic(err)
}
// write the whole body at once
err = ioutil.WriteFile("output.txt", b, 0644)
if err != nil {
panic(err)
}
}
C'est de la tarte! Mais utilisez-le uniquement si vous êtes sûr que vous ne traitez pas avec de gros fichiers.