儘管主題上有很多SO線程,但我在解析CSV時遇到了問題。這是從AdWords關鍵字規劃工具下載的.csv文件。以前,Adwords可以選擇將數據導出爲「普通CSV」(可以使用Ruby CSV庫進行分析),現在選項可以是Adwords CSV或Excel CSV。這兩種格式導致此問題(通過一個終端會話所示):使用不同的編碼和庫解析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:
在評論中使用建議,這裏的當前版本:
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
這不工作 - 現在我得到一個「文件名太長」錯誤。
你能提供一個你正試圖解析的文件的例子嗎? – benjaminjosephw
你能不能把'file.read'放在沒有異常的地方? –
@benjaminjosephw下面是我正在使用的確切文件:http://jamesabbottdd.com/examples/testfile.csv – abbottjam