go的大文件内容比较

最近想开发一个工具用于diff两个文件的内容。这些文件大小都是几G大小的文件(每行表示一条记录)。目的是找出两个文件中有哪些记录不同。之前版本是直接使用 ioutil.ReadFile进行处理的。但实现过程中出现内存不断占用上涨的情况。

想请教下各位是否有使用go针对大文件diff的经验,想了解下如何才能不占用过多的内存完成内容比对

已邀请:

sheepbao - https://sheepbao.github.io 爱go,爱编程,领域网络开发,流媒体、分布式、网络加速

赞同来自: thimoonxy domac

ReadFile reads the file named by filename and returns the contents. A successful call returns err == nil, not err == EOF. Because ReadFile reads the whole file, it does not treat an EOF from Read as an error to be reported. 上面是官方文档该函数的说明,说的很明白了,ioutil.ReadFile 是打开文件描述,然后一次读取所有的内容,这样当然会导致内存越来越大。所以你应该自己打开文件,然后读取每一行,标准库已经有读取每行的实现,请参考https://gowalker.org/bufio#Reader_ReadLine

littledriver

赞同来自: domac

我们之前在前段时间的 hackathon 上面做的 project 遇到过类似问题,可以看看bsdiff的 go 实现方式。

Xanthus - 红红火火恍恍惚惚

赞同来自:

是不是缓冲区太大了

domac - life should be func

赞同来自:

今天试了下下面的方式:

f, err := os.Open(filepath)
    if err != nil {
        return err
    }
    defer f.Close()

    s := bufio.NewScanner(f)
    for s.Scan() {
        if t := s.Text(); t != "" {
            //...省略具体结果逻辑
        }
    }

大文件的内容可以顺利读入了。

其实现在耗内存的是diff的功能上了, 网上的算法我看很多都是 “最长公共子序列”的算法。各位有其它好的解决手段比较省内存的吗?

要回复问题请先登录注册