使用ruby流式处理并解压缩大型csv文件
我有问题需要下载,解压缩,然后逐行处理一个非常大的CSV文件.我认为让您了解文件的大小是有用的:
> big_file.zip~700mb 这是我想要发生的一些事情: >在解压缩之前不必下载整个文件 我不知道这是否可能.这就是我的想法: require 'open-uri' require 'rubyzip' require 'csv' open('http://foo.bar/big_file.zip') do |zipped| Zip::InputStream.open(zipped) do |unzipped| sleep 10 until entry = unzipped.get_next_entry && entry.name == 'big_file.csv' CSV.foreach(unzipped) do |row| # process the row,maybe write out to STDOUT or some file end end end 这是我所知道的问题: > open-uri读取整个响应并将其保存到Tempfile中,这对于这个大小的文件来说是不合适的.我可能需要直接使用Net :: HTTP,但我不知道如何做到这一点仍然得到一个IO. 我不知道这是否是正确的做法.也许一些EventMachine解决方案会更好(虽然我以前从未使用过EventMachine,但如果它对这样的东西更好用,我就是为了它). 解决方法
自从我发布这个问题已经有一段时间了,如果有人遇到它,我认为可能值得分享我发现的东西.
>对于我处理Ruby标准库CSV的行数太慢了.我的csv文件很简单,无论如何我都不需要处理引用的字符串或类型强制.只需使用IO#gets然后在逗号上拆分行就容易多了. 我最终使用的解决方案是将文件下载到磁盘,然后使用Ruby的open3库和Linux unzip包从zip中流式传输未压缩的csv文件. require 'open3' IO.popen('unzip -p /path/to/big_file.zip big_file.csv','rb') do |io| line = io.gets # do stuff to process the CSV line end 解压缩时-p开关将提取的文件发送到stdout. IO.popen然后使用管道在ruby中创建一个IO对象.工作得很好.如果你想要额外的处理,你也可以将它与CSV一起使用,这对我来说太慢了. require 'open3' require 'csv' IO.popen('unzip -p /path/to/big_file.zip big_file.csv','rb') do |io| CSV.foreach(io) do |row| # process the row end end (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |