(Ruby 2.5( 我有一个方法可以读取和解析通过Alchemy CMS上传的csv文件
def process_csv(csv_file, current_user_id, original_filename)
lock_importer
errors = []
index = 0
string_converter = lambda { |field| field.strip }
total = CSV.foreach(csv_file, headers: true).count
csv_string = csv_file.read.encode!("UTF-8", "iso-8859-1", invalid: :replace)
CSV.parse(csv_string, headers: true, header_converters: :symbol, skip_blanks: true, converters: [string_converter] ) do |row|
# do other stuff
end
但是当我尝试上传一个具有包含特殊字符的字符串(名称(的 csv 文件时,我会收到Invalid Byte Sequence in UTF-8
错误。我正在尝试测试值N'öt Réal Stô'rë
.
我已经尝试了一些在网上找到的解决方案,但没有运气 - 有什么建议吗?
目前还不清楚你的csv_file
是什么。我想它是一个文件对象。
有时我从Excel中获取CSV作为UTF-16。因此,让我们尝试一个例子:
我有一个存储在 UTF-16BE 中的 csv 文件,其中包含以下内容:
line;comment;UmlautÄ
1;Das ist UTF-16 BE;Ä
2;öüäÖÄÜ;Ä
如果我执行以下代码:
require 'csv'
def process_csv(csv_file)
csv_string = csv_file.read#.encode!("UTF-8", "iso-8859-1", invalid: :replace)
CSV.parse(csv_string, headers: true, skip_blanks: true, col_sep: ';') do |row|
p row # do other stuff
end
end
process_csv(File.open('example_utf16BE.txt'))
然后我也得到一个Invalid byte sequence in UTF-8
错误。
如果我使用
process_csv(File.open('example_utf16BE.txt', 'rb', encoding: 'BOM|utf-16BE'))
然后一切正常。
所以我想,你会得到一个 wron 编码中的 File-对象,代码csv_file.read.encode!("UTF-8", "iso-8859-1", invalid: :replace)
是修复此问题的代码部分。
您可以执行的操作:
添加到您的代码:
p csv_file
p csv_file.external_encoding
你应该得到
#<File:example_utf16BE.txt>
#<Encoding:UTF-16BE>
现在检查文件(在我的示例中:example_utf16BE.txt
是否真的具有第二行的编码。
如果没有,请尝试调整文件对象的创建。 如果无法做到这一点,则可以尝试在读取内容之前使用csv_file.set_encoding 'utf-8'
更改编码。