如何使用 Go 读取/写入文件

新手上路,请多包涵

我一直在尝试自己学习 Go,但我一直难以尝试读取和写入普通文件。

我可以得到 inFile, _ := os.Open(INFILE, 0, 0) ,但实际上获取文件的内容没有意义,因为读取函数需要 []byte 作为参数。

 func (file *File) Read(b []byte) (n int, err Error)

原文由 Seth Hoenig 发布,翻译遵循 CC BY-SA 4.0 许可协议

阅读 438
2 个回答

让我们制作一个兼容 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.Openos.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)
    }
}

非常简单!但是只有当你确定你不是在处理大文件时才使用它。

原文由 Mostafa 发布,翻译遵循 CC BY-SA 4.0 许可协议

这是一个很好的版本:

 package main

import (
  "io/ioutil";
  )

func main() {
  contents,_ := ioutil.ReadFile("plikTekstowy.txt")
  println(string(contents))
  ioutil.WriteFile("filename", contents, 0644)
}

原文由 Piotr 发布,翻译遵循 CC BY-SA 4.0 许可协议

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题