本文摘自php中文网,作者藏色散人,侵删。
下面由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》频道 >>
老貘
一个与时俱进的Go编程知识库。
转载请注明出处:木庄网络博客 » 两个Golang超大文件读取的方案