两个Golang超大文件读取的方案


本文摘自php中文网,作者藏色散人,侵删。

下面由golang教程栏目给大家介绍两个Golang超大文件读取的方案,希望对需要的朋友有所帮助!

Golang超大文件读取的两个方案

1.流处理方式

2.分片处理

去年的面试中我被问到超大文件你怎么处理,这个问题确实当时没多想,回来之后仔细研究和讨论了下这个问题,对大文件读取做了一个分析

比如我们有一个log文件,运行了几年,有100G之大。按照我们之前的操作可能代码会这样写:

1

2

3

4

5

6

7

func ReadFile(filePath string) []byte{

    content, err := ioutil.ReadFile(filePath)

    if err != nil {

        log.Println("Read error")

    }

    return content

}

上面的代码读取几兆的文件可以,但是如果大于你本身及其内存,那就直接翻车了。因为上面的代码,是把文件所有的内容全部都读取到内存之后返回,几兆的文件,你内存够大可以处理,但是一旦上几百兆的文件,就没那么好处理了。那么,正确的方法有两种,第一个是使用流处理方式代码如下:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

func ReadFile(filePath string, handle func(string)) error {

    f, err := os.Open(filePath)

    defer f.Close()

    if err != nil {

        return err

    }

    buf := bufio.NewReader(f)

 

    for {

        line, err := buf.ReadLine("\n")

        line = strings.TrimSpace(line)

        handle(line)

        if err != nil {

            if err == io.EOF{

                return nil

            }

            return err

        }

        return nil

    }

}

第二个方案就是分片处理,当读取的是二进制文件,没有换行符的时候,使用下面的方案一样处理大文件

1

2

3

4

5

6

7

8

9

10

11

12

func ReadBigFile(fileName string, handle func([]byte)) error {

    f, err := os.Open(fileName)

    if err != nil {

        fmt.Println("can't opened this file")

        return err

    }

    defer f.Close()

    s := make([]byte, 4096)

    for {

        switch nr, err := f.Read(s[:]); true {

        case nr < 0:

            fmt.Fprintf(os.Stderr, "cat: error reading: %s\n

更多相关技术文章,请访问go语言教程栏目!

以上就是两个Golang超大文件读取的方案的详细内容,更多文章请关注木庄网络博客!!

相关阅读 >>

json分级解析及数字解析实践

Go-carbon 1.4.0 版本发布,新增获取世纪和季度开始和结束时间方法

Go stl 查询 db 引发的内存泄露

Go学习(第一天)

lal-开源Go语言音视频流媒体服务器

Golang实现京东支付v2版本

聊聊Gost的deltacompare

[系列] Go - 统一定义 api 错误码

Go语言函数方法

手撸Golang 基本数据结构与算法 冒泡排序

更多相关阅读请进入《Go》频道 >>




打赏

取消

感谢您的支持,我会继续努力的!

扫码支持
扫码打赏,您说多少就多少

打开支付宝扫一扫,即可进行扫码打赏哦

分享从这里开始,精彩与您同在

评论

管理员已关闭评论功能...