走。使用巨大的csv文件

时间:2016-04-05 01:17:29

标签: csv go

我们有大数据集 - 几十个csv文件,每个〜130Gb。 我们必须在csv表上模拟sql查询。

当我们在测试1.1 Gb文件上使用encoding/csv读取测试表时 - 程序分配526 Gb的虚拟内存。为什么?当我们使用csv.Reader方法时,reader.Read()就像生成器一样工作,或者它在内存中保留行?

code后完整codereview

UPD

读取文件如:

rf, err := os.Open(input_file)
if err != nil {
    log.Fatal("Error: %s", err)
}
r := csv.NewReader(rf)
for {
    record, err := r.Read()
}

因内存错误而落在record, err := r.Read()行。

UPD2 读取过程中的内存快照:

 2731.44MB 94.63% 94.63%  2731.44MB 94.63%  encoding/csv.(*Reader).parseRecord
     151MB  5.23% 99.86%  2885.96MB   100%  main.main
         0     0% 99.86%  2731.44MB 94.63%  encoding/csv.(*Reader).Read
         0     0% 99.86%  2886.49MB   100%  runtime.goexit
         0     0% 99.86%  2886.49MB   100%  runtime.main

1 个答案:

答案 0 :(得分:4)

很可能没有检测到换行符并将其作为单个记录读取。

https://golang.org/src/encoding/csv/reader.go?s=4071:4123#L124

如果您按照第210行的代码操作,则会看到它查找'\n'

当某些系统将其导出时,我经常看到换行符定义为\n\r,认为它们实际上是Windows智能的,实际上它是错误的。正确的Windows换行符为\r\n

或者,您可以编写一个自定义Scanner,使用输入中的任何技术为您排除线条,并将其用作io.Reader的{​​{1}}输入。例如,要使用上面提到的无效csv.Reader