聊聊Go语言读文件的几种优雅姿势

读取文件是程序员日常工作中最常见的任务之一。您可以根据需要以不同的方式进行操作。在本教程中,我们告诉你如何一次读取整个文件、一行行读取、一字一句读取文件、以及分块去读。所有这些方法在 Go 🙂 中都非常简单。

读取整个文件

在 Go 中读取文本或二进制文件的最简单方法是使用os包中的ReadFile()函数。此函数将文件的全部内容读到一个byte切片,因此在尝试读取大文件时应该注意 - 在这种情况下,您应该逐行分块读取文件。对于小文件,这种方式绰绰有余。

如果您使用的是 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!

逐字的读取文件

逐字读取文件与逐行读取几乎相同。您只需要将Scannersplit功能从默认的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
!
云原生生态圈版权声明:
作者:云原生生态圈
文章标题: 聊聊Go语言读文件的几种优雅姿势
链接:https://devopsman.cn/archives/108
来源:云原生生态圈
投稿联系: cloud.native@qq.com 文章版权归作者所有,未经允许请勿转载。
THE END
分享
二维码
打赏
< <上一篇
下一篇>>
文章目录
关闭
目 录