Lassen Sie uns eine Go 1-kompatible Liste aller Möglichkeiten zum Lesen und Schreiben von Dateien in Go erstellen.
Da sich die Datei-API in letzter Zeit geändert hat und die meisten anderen Antworten mit Go 1 nicht funktionieren, fehlt ihnen auch, bufio
was meiner Meinung nach wichtig ist.
In den folgenden Beispielen kopiere ich eine Datei, indem ich daraus lese und in die Zieldatei schreibe.
Beginnen Sie mit den Grundlagen
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)
}
}
}
Hier habe ich verwendet os.Open
und os.Create
welche sind praktische Wrapper herum os.OpenFile
. Wir müssen normalerweise nicht OpenFile
direkt anrufen .
Beachten Sie die Behandlung von EOF. Read
versucht buf
bei jedem Aufruf zu füllen und gibt io.EOF
als Fehler zurück, wenn dabei das Dateiende erreicht wird. In diesem Fall buf
werden weiterhin Daten gespeichert. Nachfolgende Aufrufe von geben Read
Null als Anzahl der gelesenen Bytes und io.EOF
als Fehler zurück. Jeder andere Fehler führt zu einer Panik.
Verwenden von 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
fungiert hier nur als Puffer, weil wir nicht viel mit Daten zu tun haben. In den meisten anderen Situationen (insbesondere bei Textdateien) bufio
ist dies sehr nützlich, da wir eine schöne API zum einfachen und flexiblen Lesen und Schreiben haben, während die Pufferung hinter den Kulissen erfolgt.
Verwenden von 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)
}
}
Einfach wie Torte! Verwenden Sie es jedoch nur, wenn Sie sicher sind, dass Sie nicht mit großen Dateien zu tun haben.