在ruby中处理大型CSV文件(20G)

fen*_*nec 4 ruby csv parsing

我正在解决一些小问题,并对如何解决它有一些建议:给定一个列数和行数未知的csv文件,输出一个列的列表,其中包含值和每个值重复的次数.没有使用任何库.

如果文件很小,这应该不是问题,但是当它是几个Gigs时,我得到NoM​​emoryError:无法分配内存.有没有办法创建一个哈希并从磁盘读取而不是将文件加载到内存?你可以在perl中使用绑定哈希来做到这一点

编辑:IO#foreach会将文件加载到内存中吗?File.open(filename).each怎么样?

mar*_*ius 21

一次读取一行文件,随时丢弃每一行:

open("big.csv") do |csv|
  csv.each_line do |line|
    values = line.split(",")
    # process the values
  end
end
Run Code Online (Sandbox Code Playgroud)

使用此方法,您永远不会耗尽内存.


Jan*_*Jan 6

你一次读完整个文件吗?阅读它在每行的基础上,即,使用ruby -pe,ruby -ne$stdin.each应减少由被处理垃圾收集线的存储器使用量.

data = {}
$stdin.each do |line|
  # Process line, store results in the data hash.
end
Run Code Online (Sandbox Code Playgroud)

将其保存为script.rb并将巨大的CSV文件传输到此脚本的标准输入中:

ruby script.rb < data.csv
Run Code Online (Sandbox Code Playgroud)

如果您不想从标准输入读取,我们需要进行一些小改动.

data = {}
File.open("data.csv").each do |line|
  # Process line, store results in the data hash.
end
Run Code Online (Sandbox Code Playgroud)

  • @fenec,是什么让你认为这个版本不纯? (2认同)