侧边栏壁纸
博主头像
云原生生态圈博主等级

让人迷茫的原因只有一个,那就是本该拼命的年纪,却想的太多,做得太少。

  • 累计撰写 51 篇文章
  • 累计创建 61 个标签
  • 累计收到 5 条评论

目 录CONTENT

文章目录
GO

Go语言读取文件姿势大全

云原生生态圈
2022-03-16 / 0 评论 / 0 点赞 / 262 阅读 / 2,204 字 / 正在检测是否收录...
温馨提示:
本文最后更新于 2022-03-30,若内容或图片失效,请留言反馈。部分素材来自网络,若不小心影响到您的利益,请联系我们删除。

读取文件是程序员日常工作中最常见的任务之一。您可以根据需要以不同的方式进行操作。在本教程中,我们告诉你如何一次读取整个文件、一行行读取、一字一句读取文件、以及分块去读。所有这些方法在 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
!
0

评论区