让我们列出与Go 1兼容的清单,其中列出了在Go中读写文件的所有方式。
由于文件API最近已更改,并且大多数其他答案不适用于Go1。他们也错过了
bufio重要的恕我直言。
在以下示例中,我通过读取文件并将其写入目标文件来复制文件。
从基础开始
package mainimport ( "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) } }}在这里,我使用了,
os.Open并且
os.Create它们是方便的包装器
os.OpenFile。我们通常不需要
OpenFile直接致电。
注意处理EOF。
Read尝试填充
buf每个调用,并
io.EOF在到达文件末尾时返回错误。在这种情况下
buf仍将保留数据。随之而来的调用
Read返回零作为读取的字节数,并且与
io.EOF错误相同。任何其他错误都会导致恐慌。
使用bufio
package mainimport ( "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在这里只是充当缓冲区,因为我们与数据无关。在大多数其他情况下(尤其是文本文件),
bufio它为我们提供了一个很好的API,可轻松灵活地进行读写,同时还可以处理后台缓冲,因此非常有用。
使用ioutil
package mainimport ( "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) }}非常简单!但是,只有在确定不处理大文件时才使用它。



