读取文件是程序员日常工作中最常见的任务之一。您可以根据需要以不同的方式进行操作。在本教程中,我们告诉你如何一次读取整个文件、一行行读取、一字一句读取文件、以及分块去读。所有这些方法在 Go ? 中都非常简单。
在 Go 中读取文本或二进制文件的最简单方法是使用os[1]包中的ReadFile()
函数。此函数将文件的全部内容读到一个byte切片,因此在尝试读取大文件时应该注意 - 在这种情况下,您应该逐行
或分块
读取文件。对于小文件,这种方式绰绰有余。
“如果您使用的是 1.16 之前的 Go 版本,您将
ReadFile()
在`ioutil`[2]包中找到该功能。
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
的split
功能从**默认的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
的byte切片作为缓冲区,用于存储后续读取的字节。使用Read()
方法加载文件数据的下一个块。当发生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
!
[1]
os: https://golang.org/pkg/os
[2]
ioutil: https://golang.org/pkg/io/ioutil