在Go中读取一个文件的方法

128 阅读3分钟

读取文件是程序员日常工作中最常见的任务之一。根据你的需要,你可以用不同的方式进行。在本教程中,我们将向你展示如何一次性读取整个文件逐行逐字分块 读取。所有这些方法在Go🙂中都是非常简单的。

读取整个文件

在Go中读取文本或二进制文件的最简单方法是使用 ReadFile()中的函数。 os包中的函数。这个函数将文件的全部内容读成一个字节片,所以当你试图读取一个大文件时,你应该小心--在这种情况下,你应该逐行或分块地读取文件。对于小文件,这个功能是绰绰有余的。

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

package main
import (
"fmt"
"log"
"os"
)
func main() {
content, err := os.ReadFile("file.txt")
if err != nil {
log.Fatal(err)
}
fmt.Println(string(content))
}

输出

Hello World!
This is txt file read by Go!

逐行读取一个文件

要逐行读取一个文件,我们可以使用一个方便的 bufio.Scanner结构。它的构造函数。 NewScanner(),接收一个已打开的文件(记得在操作完成后关闭该文件,例如,使用defer 语句),并让你通过 Scan()Text()方法。使用 Err()方法,你可以检查在读文件时遇到的错误。

package main
import (
"bufio"
"fmt"
"log"
"os"
)
func main() {
// open file
f, err := os.Open("file.txt")
if err != nil {
log.Fatal(err)
}
// remember to close the file at the end of the program
defer f.Close()
// read the file line by line using scanner
scanner := bufio.NewScanner(f)
for scanner.Scan() {
// do something with a line
fmt.Printf("line: %s\n", scanner.Text())
}
if err := scanner.Err(); err != nil {
log.Fatal(err)
}
}

输出

line: Hello World!
line: This is txt file read by Go!

一个字一个字的读一个文件

逐字阅读文件与逐行阅读几乎是一样的。你只需要把文件的分割功能从默认的 Scanner的分割功能,从默认的 ScanLines()改为 ScanWords().

package main
import (
"bufio"
"fmt"
"log"
"os"
)
func main() {
// open file
f, err := os.Open("file.txt")
if err != nil {
log.Fatal(err)
}
// remember to close the file at the end of the program
defer f.Close()
// read the file word by word using scanner
scanner := bufio.NewScanner(f)
scanner.Split(bufio.ScanWords)
for scanner.Scan() {
// do something with a word
fmt.Println(scanner.Text())
}
if err := scanner.Err(); err != nil {
log.Fatal(err)
}
}

输出

Hello
World!
This
is
txt
file
read
by
Go!

分块读取文件

当你有一个非常大的文件或不想把整个文件存储在内存中时,你可以以固定大小的块来读取文件。在这种情况下,你需要创建一个指定大小的字节片(在本例中为chunkSize )作为缓冲区,用于存储随后的读取字节。使用 Read()方法的 File类型的方法,我们可以加载文件数据的下一个块。读取循环在以下情况下结束 io.EOF错误发生时,读取循环就结束了,表明文件已经结束。

package main
import (
"fmt"
"io"
"log"
"os"
)
const chunkSize = 10
func main() {
// open file
f, err := os.Open("file.txt")
if err != nil {
log.Fatal(err)
}
// remember to close the file at the end of the program
defer f.Close()
buf := make([]byte, chunkSize)
for {
n, err := f.Read(buf)
if err != nil && err != io.EOF {
log.Fatal(err)
}
if err == io.EOF {
break
}
fmt.Println(string(buf[:n]))
}
}

输出

Hello Worl
d!
This is
txt file
read by Go
!