回答

收藏

如何使用 Go 从文件读/写

技术问答 技术问答 247 人阅读 | 0 人回复 | 2023-09-12

我一直在尝试自己学习 Go,但我一直在尝试读写普通文件。2 B0 O5 i4 d1 {9 o, i! J
我可以达到inFile,_ := os.Open(INFILE,0,0),但实际上获取文件的内容毫无意义,因为 read 函数将 a[]byte作为参数。
; L# _8 K) u3 ?
    func (file *File) Read(b []byte) (n int,err Error)
    + i3 r! g3 T3 A5 ]7 \5 Q$ ^# f5 L
               
" V; x+ ~* k8 \5 L) [    解决方案:                                                                : V- ]) e# z. L4 V6 [5 h
                                                                让我们做一个 Go 1 兼容列表列在 Go 中读写文件的方式。
' b. f3 {/ p3 K- P  z因为文件 API 最近发生了变化,并且大多数其他答案不适用于 Go 1.他们也错过了bufio重要的恕我直言。
( F" z* X$ ~) O! w在下面的例子中,我通过阅读文件并写入目标文件来复制文件。& @! b6 p2 q  T# g% ~8 c/ f
从基础开始
! T* a$ Q3 S3 ~# \  C4 F[code]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)      code]我在这里用过os.Open和os.Create包装方便os.OpenFile。我们通常不需要它OpenFile直接调用。0 N; H* t2 ]. r3 e9 a( {! w7 @2 N
注意处理EOF。Read尝试填充buf每个调用,io.EOF到达文件末尾时,返回错误。在这种情况下buf数据仍将保存。然后调用Read返回零作为读取的字节数io.EOF同样的错误。任何其他错误都会导致恐慌。  U. X4 J% Q! r$ l5 G9 n' W% _. x0 d5 m
使用 bufio
( s0 P6 n! K* j+ A* L: D6 H[code]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)  code]bufio在这里只是充当缓冲区,因为我们与数据没有太大关系。在大多数其他情况下(特别是文本文件)bufio它非常有用,它为我们提供了一个很好的 API,用于轻松灵活的读写,同时在后台处理缓冲。
" Q0 r- C) `+ e0 @; f注意:以下代码适用于旧 Go 版本(Go 1.15 及以前)。事情变了。看看新的答案。' Z1 X: {' b( F  ]# l2 N4 `
使用 ioutil
; ~- U. w/ j+ W( i- h[code]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)  code]非常简单!但只有在你确定你没有处理大文件时才使用它。
分享到:
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则