Golang 如何以字符串形式逐行读取文件
在Golang中,我们可以通过标准库中的bufio包实现逐行读取文件并以字符串形式输出。下面我们将介绍如何使用bufio包实现此功能。
代码示例
package main
import (
"bufio"
"fmt"
"os"
)
func main() {
file, err := os.Open("example.txt")
if err != nil {
fmt.Println(err)
return
}
defer file.Close()
scanner := bufio.NewScanner(file)
for scanner.Scan() {
fmt.Println(scanner.Text())
}
if err := scanner.Err(); err != nil {
fmt.Println(err)
return
}
}
在上述代码中,我们通过os.Open
函数打开要读取的文件,并通过bufio.NewScanner
函数创建了一个扫描器。接着,我们使用for
循环一行一行地读取文件并输出输出到控制台上。
说明
需要注意的是,在使用bufio.NewScanner
函数创建扫描器时,我们并没有指定扫描器的缓冲区大小。这是因为bufio
包默认会分配一个4096
字节的缓冲区。
同时,上述代码所示的方法适用于读取相对较小的文件。如果需要处理大文件,建议使用bufio
包中的ReadSlice
和ReadBytes
函数,其支持更高效的内存管理。
效率
我们可以使用time
包中的Now()
函数来对比使用不同函数读取文件所需要的时间。
package main
import (
"bufio"
"fmt"
"os"
"time"
)
func readWithScanner(filename string) {
file, err := os.Open(filename)
if err != nil {
fmt.Println(err)
return
}
defer file.Close()
scanner := bufio.NewScanner(file)
for scanner.Scan() {
_ = scanner.Text()
}
if err := scanner.Err(); err != nil {
fmt.Println(err)
return
}
}
func readWithReadBytes(filename string) {
file, err := os.Open(filename)
if err != nil {
fmt.Println(err)
return
}
defer file.Close()
r := bufio.NewReader(file)
var b []byte
for {
line, isPrefix, err := r.ReadLine()
if err != nil {
break
}
b = append(b, line...)
if !isPrefix {
b = append(b, '\n')
_ = string(b)
b = b[:0]
}
}
}
func main() {
filename := "example.txt"
start := time.Now()
readWithScanner(filename)
fmt.Println("Using Scanner:", time.Since(start))
start = time.Now()
readWithReadBytes(filename)
fmt.Println("Using ReadBytes:", time.Since(start))
}
上述代码通过对比readWithScanner
和readWithReadBytes
两个函数读取example.txt
所需的时间,发现ReadBytes
函数更加高效。不难理解,因为其内部使用了更为紧凑的字节数组,而不是每次扫描都生成一个新的字符串。
结论
在Golang中,我们可以使用bufio
包的NewScanner
函数和Text
方法实现逐行读取文件并以字符串形式输出。可以通过ReadSlice
和ReadBytes
函数来处理大文件,提高程序的效率。