登录
首页 >  Golang >  Go问答

使用 Go 在小内存条件下高效读取大文件

来源:stackoverflow

时间:2024-02-29 21:51:25 432浏览 收藏

Golang小白一枚,正在不断学习积累知识,现将学习到的知识记录一下,也是将我的所得分享给大家!而今天这篇文章《使用 Go 在小内存条件下高效读取大文件》带大家来了解一下##content_title##,希望对大家的知识积累有所帮助,从而弥补自己的不足,助力实战开发!


问题内容

我想从不同的文本或 JSON 或 CSV 文件中读取数据。我应该遵循哪种方法?

我有博文“文件读取”和“使用小 RAM 读取 2 GB 文本文件”,了解不同的文件读取方法。

不同的方法:

  • 分块读取文件
  • 同时读取文件块
  • 将整个文件读入内存
  • 将长字符串拆分为单词
  • 逐字扫描

用小内存读取文件最快的方法是什么?


解决方案


基本上有两种不同的方法来解析文件:文档解析和流解析。

文档解析从文件中读取数据并将其转换为可以查询的一大组对象,例如浏览器中的 html DOM。优点是您可以轻松获得完整的数据,这通常更简单。缺点是您必须将其全部存储在内存中。

dom = parse(stuff)

// now do whatever you like with the dom

流解析一次读取一个元素并将其呈现给您立即使用,然后继续处理下一个元素。

for element := range stream(stuff) {
    ...examine one element at a time...
}

优点是您不必将整个内容加载到内存中。缺点是您必须随时处理数据。这对于搜索或任何其他需要一一处理的事情非常有用。

幸运的是,go 提供了库来为您处理常见格式。

一个简单的示例是处理 csv 文件。

package main

import(
    "encoding/csv"
    "fmt"
    "log"
    "os"
    "io"
)

func main() {
    file, err := os.open("test.csv")
    if err != nil {
        log.fatal(err)
    }

    parser := csv.newreader(file)

    ...
}

我们可以将整个内容作为一个大的 [][]string 放入内存中。

records, err := parser.readall()
if err != nil {
    log.fatal(err)
}

for _,record := range records {
    fmt.println(record)
}

或者我们可以节省大量内存并一次处理一行。

for {
    record, err := parser.read()
    if err == io.eof {
        break
    }
    if err != nil {
        log.fatal(err)
    }

    fmt.println(record)
}

由于 csv 的每一行在功能上都是相同的,因此一次处理一行最有意义。

json 和 xml 更复杂,因为它们是大型嵌套结构,但它们也可以流式传输。有 an example of streaming in the encoding/json documentation

如果您的代码不是简单的循环怎么办?如果您想利用并发性怎么办?使用通道和 goroutine 使其与程序的其余部分同时运行。

records := make( chan []string )
go func() {
    parser := csv.newreader(file)

    defer close(records)
    for {
        record, err := parser.read()
        if err == io.eof {
            break
        }
        if err != nil {
            log.fatal(err)
        }

        records <- record
    }
}();

现在您可以将 records 传递给可以处理它们的函数。

func print_records( records chan []string ) {
    for record := range records {
        fmt.Println(record)
    }
}

理论要掌握,实操不能落!以上关于《使用 Go 在小内存条件下高效读取大文件》的详细介绍,大家都掌握了吧!如果想要继续提升自己的能力,那么就来关注golang学习网公众号吧!

声明:本文转载于:stackoverflow 如有侵犯,请联系study_golang@163.com删除
相关阅读
更多>
最新阅读
更多>
课程推荐
更多>