Ruby 1.9.2 - 读取并解析远程CSV

mar*_*wer 18 ruby csv parsing rvm

我正在寻找一种方法来本地读取和解析远程CSV(托管在特定网站上).

我在互联网上发现了一些有趣的例子,它们使用了FasterCSV,在ruby 1.9.2中已经合并为CSV.我发现你可以用这种方式使用gems'csv'和'open-uri'来读取远程CSV:

require 'csv'
require 'open-uri'

def read(url)
  open(url) do |f|
    f.each_line do |l|
      CSV.parse(l) do |row|
        puts row
      end
    end
  end
end
Run Code Online (Sandbox Code Playgroud)

但是当我调用这个函数时,我得到一个例外:

ERROR IOError: closed stream
Run Code Online (Sandbox Code Playgroud)

谁能解释我为什么?有什么不对的吗?我应该选择其他方法来阅读远程CSV吗?

更新

我到目前为止找到的最佳解决方案是:

def read(url)
  data = []
  begin
    open(url) do |f|
      data = CSV.parse f
    end
  rescue IOError => e
    # Silently catch the exception ...
  end

  return data
end
Run Code Online (Sandbox Code Playgroud)

但它有点似乎不那么干净.我真的不喜欢默默地捕捉异常,它不应该......

更新2

我可以使用两者重现错误

ruby 1.9.2p0 (2010-08-18 revision 29036) [x86_64-darwin10.4.0]
Run Code Online (Sandbox Code Playgroud)

ruby 1.9.2p180 (2011-02-18 revision 30909) [x86_64-darwin10.7.0]
Run Code Online (Sandbox Code Playgroud)

这是我test.rb文件中的代码:

require 'rubygems'
require 'open-uri'
require 'csv'

def read(url)
  data = []
  begin
    open(url) do |f|
      data = CSV.parse f
    end
  end

  puts data
end

read("http://www.euribor-ebf.eu/assets/modules/rateisblue/processed_files/myav_EURIBOR_2011.csv")
Run Code Online (Sandbox Code Playgroud)

这是ruby test.rb命令的输出

/Users/marzu/.rvm/rubies/ruby-1.9.2-p180/lib/ruby/1.9.1/open-uri.rb:152:in `close': closed stream (IOError)
from /Users/marzu/.rvm/rubies/ruby-1.9.2-p180/lib/ruby/1.9.1/open-uri.rb:152:in `open_uri'
from /Users/marzu/.rvm/rubies/ruby-1.9.2-p180/lib/ruby/1.9.1/open-uri.rb:671:in `open'
from /Users/marzu/.rvm/rubies/ruby-1.9.2-p180/lib/ruby/1.9.1/open-uri.rb:33:in `open'
from test.rb:8:in `read'
from test.rb:16:in `<main>'
Run Code Online (Sandbox Code Playgroud)

rvm 1.6.9在Mac OS X 10.6.7上使用.

有什么建议?

Ste*_*elm 39

在Mac OS X 10.6.7上,使用ruby r1.9.2,我得到与上面显示的相同的错误.但是使用以下代码读取CSV文件适用于提供的示例URL:

require 'rubygems'
require 'open-uri'
require 'csv'

def read(url)
 CSV.new(open(url), :headers => :first_row).each do |line|
   puts line
   puts line[0]
   puts line['FEB11']
 end
end

read("http://www.euribor-ebf.eu/assets/modules/rateisblue/processed_files/myav_EURIBOR_2011.csv")
Run Code Online (Sandbox Code Playgroud)

  • 如果你 linter 抱怨 open 存在安全问题,你可以用 `URI.parse(url).open` 重新替换它。 (4认同)