CSV 支持headers和fields的“转换器” ,它可以让您在数据传递到each
循环之前进入数据。
编写示例 CSV 文件:
csv = "First,Last,Email ,Mobile Phone ,Company,Title ,Street,City,State,Zip,Country, Birthday,Gender ,Contact Type
first,last,email ,mobile phone ,company,title ,street,city,state,zip,country, birthday,gender ,contact type
"
File.write('file_upload_example.csv', csv)
这是我的做法:
require 'csv'
csv = CSV.open('file_upload_example.csv', :headers => true)
[:convert, :header_convert].each { |c| csv.send(c) { |f| f.strip } }
csv.each do |row|
puts "First Name: #{row['First']} \nLast Name: #{row['Last']} \nEmail: #{row['Email']}"
end
哪个输出:
First Name: 'first'
Last Name: 'last'
Email: 'email'
当从文件中读取每个标题和每个字段时,转换器只需从每个标题和每个字段中去除前导和尾随空格。
此外,作为编程设计选择,不要使用以下方法将文件读入内存:
csv_text = File.read('file_upload_example.csv')
然后解析它:
csv = CSV.parse(csv_text, :headers => true)
然后循环它:
csv.each do |row|
Ruby's IO system supports "enumerating" over a file, line by line. Once my code does CSV.open
the file is readable and the each
reads each line. The entire file doesn't need to be in memory at once, which isn't scalable (though on new machines it's becoming a lot more reasonable), and, if you test, you'll find that reading a file using each
is extremely fast, probably equally fast as reading it, parsing it then iterating over the parsed file.