使用CSV库时流关闭IO错误

时间:2014-05-29 10:46:17

标签: ruby-on-rails ruby csv ruby-on-rails-4

我试图通过使用CSV库解析CSV文件来获取一系列哈希值。

我目前有这种方法有效:

def rows
  rows = []

  CSV.foreach(@csv_file.path, headers: true) do |row|
    rows << row.to_hash
  end

  rows
end

但是当我将其更改为此时,我收到stream closed错误。

def rows
  CSV.foreach(@csv_file.path, headers: true).map(&:to_hash)
end

感谢

1 个答案:

答案 0 :(得分:5)

如果查看::foreach的源代码:

def self.foreach(path, options = Hash.new, &block)
  encoding =  options.delete(:encoding)
  mode     =  "rb"
  mode     << ":#{encoding}" if encoding
  open(path, mode, options) do |csv|
    csv.each(&block)
  end
end

在内部,使用CSV::open打开文件,打开文件。因此,一旦块关闭,IO对象在内部关闭。现在,当您尝试访问已关闭的IO对象时,您将收到错误。

来自CSV::open

的文件
  

此方法与Ruby的open()调用类似,因为它会将CSV对象传递给提供的块,并在块终止时将其关闭,...

IO返回的::foreach对象实际上由方法CSV::open内的def self.foreach ...返回。

示例:

2.1.0 :016 > require 'csv'
 => true 
2.1.0 :017 > CSV.open("Gemfile")
 => <#CSV io_type:File io_path:"Gemfile" encoding:UTF-8 lineno:0 col_sep:"," row_sep:"\n" quote_char:"\""> 
2.1.0 :018 > CSV.open("Gemfile") { |c| c }
 => <#CSV io_type:File io_path:"Gemfile" encoding:UTF-8 lineno:0 col_sep:"," row_sep:"\n" quote_char:"\""> 
2.1.0 :019 > CSV.open("Gemfile") { |c| c }.read
IOError: closed stream