如何使用 Go 从文件读/写
我一直在尝试自己学习 Go,但我一直在尝试读取和写入普通文件。
我可以达到inFile, _ := os.Open(INFILE, 0, 0)
,但实际上获取文件的内容没有意义,因为 read 函数将 a[]byte
作为参数。
func (file *File) Read(b []byte) (n int, err Error)
-
让我们制作一个 Go 1 兼容的列表,列出在 Go 中读写文件的所有方式。
因为文件 API 最近发生了变化,并且大多数其他答案不适用于 Go 1。他们也错过了
bufio
重要的恕我直言。在以下示例中,我通过读取文件并写入目标文件来复制文件。
从基础开始
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) } } }
在这里,我使用了
os.Open
和os.Create
方便的包装器os.OpenFile
。我们通常不需要OpenFile
直接调用。注意处理EOF。
Read
尝试填充buf
每个调用,io.EOF
如果到达文件末尾则返回错误。在这种情况下buf
仍将保存数据。随后调用Read
返回零作为读取的字节数,与io.EOF
错误相同。任何其他错误都会导致恐慌。使用
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
在这里只是充当缓冲区,因为我们与数据没有太大关系。在大多数其他情况下(特别是文本文件)bufio
非常有用,它为我们提供了一个很好的 API,用于轻松灵活地读写,同时它在后台处理缓冲。
注意:以下代码适用于较旧的 Go 版本(Go 1.15 及之前)。事情变了。对于新的方式,看看这个答案。
使用
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) } }
非常简单!但是只有在您确定您没有处理大文件时才使用它。