【发布时间】:2014-01-10 03:48:28
【问题描述】:
尽管有许多关于该主题的 SO 线程,但我在解析 CSV 时遇到了问题。它是从 Adwords 关键字规划师下载的 .csv 文件。以前,Adwords 可以选择将数据导出为“普通 CSV”(可以使用 Ruby CSV 库进行解析),现在可以选择 Adwords CSV 或 Excel CSV。这两种格式都会导致此问题(以终端会话为例):
file = File.open('public/uploads/testfile.csv')
=> #<File:public/uploads/testfile.csv>
file.read.encoding
=> #<Encoding:UTF-8>
require 'csv'
=> true
CSV.foreach(file) { |row| puts row }
ArgumentError: invalid byte sequence in UTF-8
让我们更改编码,看看是否有帮助:
file.close
=> nil
file = File.open("public/uploads/testfile.csv", "r:ISO-8859-1")
=> #<File:public/uploads/testfile.csv>
file.read.encoding
=> #<Encoding:ISO-8859-1>
CSV.foreach(file) { |row| puts row }
ArgumentError: invalid byte sequence in UTF-8
让我们尝试使用不同的 CSV 库:
require 'smarter_csv'
=> true
file.close
=> nil
file = SmarterCSV.process('public/uploads/testfile.csv')
ArgumentError: invalid byte sequence in UTF-8
这是一个没有双赢的局面吗?我必须推出自己的 CSV 解析器吗?
我正在使用 Ruby 1.9.3p374。谢谢!
更新 1:
使用 cmets 中的建议,这是当前版本:
file_contents = File.open("public/uploads/new-format/testfile-adwords.csv", 'rb').read
require 'iconv' unless String.method_defined?(:encode)
if String.method_defined?(:encode)
file_contents.encode!('UTF-16', 'UTF-8', :invalid => :replace, :replace => '')
file_contents.encode!('UTF-8', 'UTF-16')
else
ic = Iconv.new('UTF-8', 'UTF-8//IGNORE')
file_contents = ic.iconv(file_contents)
end
file_contents.gsub!(/\0/, '') #needed because otherwise, I get "string contains null byte (ArgumentError)"
CSV.foreach(file_contents, :headers => true, :header_converters => :symbol) do |row|
puts row
end
这不起作用 - 现在我收到“文件名太长”错误。
【问题讨论】:
-
你能提供一个你试图解析的文件的例子吗?
-
你可以
puts file.read无一例外吗? -
@benjaminjosephw 这是我正在使用的确切文件:jamesabbottdd.com/examples/testfile.csv
-
@majioa
CSV.foreach(file) { puts file.read }在同一行产生完全相同的错误:来自 ../.rvm/rubies/ruby-1.9.3-p374/lib/ruby/1.9.1/csv .rb:2058:in `=~' -
@user906230 - 这有帮助吗? stackoverflow.com/a/8873922/2463468
标签: ruby parsing csv google-ads-api