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, bufiowas 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.Openund os.Createwelche sind praktische Wrapper herum os.OpenFile. Wir müssen normalerweise nicht OpenFiledirekt anrufen .
Beachten Sie die Behandlung von EOF. Readversucht bufbei jedem Aufruf zu füllen und gibt io.EOFals Fehler zurück, wenn dabei das Dateiende erreicht wird. In diesem Fall bufwerden weiterhin Daten gespeichert. Nachfolgende Aufrufe von geben ReadNull als Anzahl der gelesenen Bytes und io.EOFals 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)
}
}
bufiofungiert hier nur als Puffer, weil wir nicht viel mit Daten zu tun haben. In den meisten anderen Situationen (insbesondere bei Textdateien) bufioist 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.