在Go中写入文件的方法

802 阅读3分钟

Go对文件操作有很好的内置支持。使用这个 os包,你可以轻松地打开、读出、写入和关闭文件。在这个例子中,我们专注于向文件写入数据。我们向你展示了如何以不同的方式写入文本和二进制数据--一次性写入整个数据、逐行写入、以字节数组的方式写入特定位置、或以缓冲的方式写入。

一次性将整个内容写到一个文件中

向文件写入数据的最短方法是使用 os.WriteFile()函数。它需要三个输入参数:

  1. 我们想写入的文件的路径
  2. 我们要写到文件的字节数据
  3. 将被创建的文件的权限位

创建和关闭文件是由函数本身完成的,所以不需要在写之前和写之后创建或关闭文件。

如果你使用的Go版本早于1.16,你会发现 WriteFile()函数在 ioutil包中找到。

package main
import (
"log"
"os"
)
func main() {
if err := os.WriteFile("file.txt", []byte("Hello GOSAMPLES!"), 0666); err != nil {
log.Fatal(err)
}
}

逐行向文件写入文本数据

如果你把文件的行数放在单独的变量、数组中,或者想在写一行之前做一些处理,你可以用函数逐行写数据。 func (*File) WriteString()方法逐行写入数据。你需要做的就是创建一个文件,将你的字符串写入其中,最后关闭该文件。

package main
import (
"log"
"os"
)
var lines = []string{
"Go",
"is",
"the",
"best",
"programming",
"language",
"in",
"the",
"world",
}
func main() {
// create file
f, err := os.Create("file.txt")
if err != nil {
log.Fatal(err)
}
// remember to close the file
defer f.Close()
for _, line := range lines {
_, err := f.WriteString(line + "\n")
if err != nil {
log.Fatal(err)
}
}
}

将字节数据写到文件中

与逐行写入字符串一样,我们也可以使用方法写入字节数据。 func (*File) Write()方法或 func (*File) WriteAt()如果你想在一个给定的偏移量上写数据的话。

package main
import (
"log"
"os"
)
var bytes = []byte{
0x47, // G
0x4f, // O
0x20, // <space>
0x20, // <space>
0x20, // <space>
0x50, // P
0x4c, // L
0x45, // E
0x53, // S
}
var additionalBytes = []byte{
0x53, // S
0x41, // A
0x4d, // M
}
func main() {
// create file
f, err := os.Create("file.txt")
if err != nil {
log.Fatal(err)
}
// remember to close the file
defer f.Close()
// write bytes to the file
_, err = f.Write(bytes)
if err != nil {
log.Fatal(err)
}
// write additional bytes to the file, start at index 2
_, err = f.WriteAt(additionalBytes, 2)
if err != nil {
log.Fatal(err)
}
}

将格式化的字符串写到文件中

除了这些 File方法,我们还可以使用 fmt.Fprintln()函数来向文件写入数据。这个函数格式化它的操作数,在它们之间添加空格,在最后添加一个新行,并将输出写入写入器(第一个参数)。它非常适用于简单的行格式化或将一个struct 的字符串表示写到一个文件中。

package main
import (
"fmt"
"log"
"os"
)
var lines = []string{
"Go",
"is",
"the",
"best",
"programming",
"language",
"in",
"the",
"world",
}
func main() {
// create file
f, err := os.Create("file.txt")
if err != nil {
log.Fatal(err)
}
// remember to close the file
defer f.Close()
for _, line := range lines {
_, err := fmt.Fprintln(f, "*", line, "*")
if err != nil {
log.Fatal(err)
}
}
}

使用缓冲写入器向文件写入数据

如果你经常向文件写入少量的数据,会损害你的程序的性能。每次写入都是一个昂贵的系统调用,如果你不需要立即更新文件,那么把这些小的写入分组为一个更好的主意。要做到这一点,我们可以使用 bufio.Writer结构。它的写入函数并不直接将数据保存到文件中,而是一直保存到下面的缓冲区满了(默认大小为4096字节)或 Flush()方法被调用。所以要确保在完成写入后调用 Flush()来将剩余的数据保存到文件中。

package main
import (
"bufio"
"log"
"os"
)
var lines = []string{
"Go",
"is",
"the",
"best",
"programming",
"language",
"in",
"the",
"world",
}
func main() {
// create file
f, err := os.Create("file.txt")
if err != nil {
log.Fatal(err)
}
// remember to close the file
defer f.Close()
// create new buffer
buffer := bufio.NewWriter(f)
for _, line := range lines {
_, err := buffer.WriteString(line + "\n")
if err != nil {
log.Fatal(err)
}
}
// flush buffered data to the file
if err := buffer.Flush(); err != nil {
log.Fatal(err)
}
}