Lassen Sie uns eine Go 1-kompatible Liste aller Möglichkeiten erstellen, Dateien in Go zu lesen und zu schreiben.
Weil sich die Datei-API vor kurzem geändert hat und die meisten anderen Antworten nicht mit Go 1 funktionieren. Sie vermissen auch bufio
was IMHO wichtig ist.
In den folgenden Beispielen kopiere ich eine Datei, indem ich aus ihr 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 os.Open
y os.Create
die praktische Umhüllungen sind für os.OpenFile
. Normalerweise müssen wir nicht anrufen OpenFile
direkt.
Hinweis zur Behandlung von EOF. Read
versucht zu füllen buf
bei jedem Aufruf, und gibt io.EOF
als Fehler, wenn er dabei das Ende der Datei erreicht. In diesem Fall buf
noch Daten enthalten. Folgerichtige Aufrufe von Read
gibt Null als Anzahl der gelesenen Bytes zurück und dasselbe io.EOF
als Fehler. Jeder andere Fehler führt zu einer Panik.
Verwendung 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
dient hier nur als Puffer, denn wir haben nicht viel mit Daten zu tun. In den meisten anderen Situationen (besonders bei Textdateien) bufio
ist sehr nützlich, da es uns eine schöne API für einfaches und flexibles Lesen und Schreiben, während es im Hintergrund die Pufferung übernimmt.
Nota: Der folgende Code ist für ältere Go-Versionen (Go 1.15 und früher). Die Dinge haben sich geändert. Für den neuen Weg, schauen Sie sich an diese Antwort .
Verwendung 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)
}
}
Ein Kinderspiel! Verwenden Sie es aber nur, wenn Sie sicher sind, dass Sie es nicht mit großen Dateien zu tun haben.