我正在使用看似具有UTF-16LE编码的文件。如果我跑
File.read(file, :encoding => 'utf-16le')
该文件的第一行是:
"<U+FEFF>=\"25/09/2013\"\t18:39:17\t=\"Unknown\"\t=\"+15168608203\"\t\"Message.\"\r\n
如果我使用类似
的内容阅读文件csv_text = File.read(file, :encoding => 'utf-16le')
我收到错误说明
ASCII incompatible encoding needs binmode (ArgumentError)
如果我将上面的编码切换到
csv_text = File.read(file, :encoding => 'utf-8')
我将其转到代码的SmarterCSV
部分,但收到错误消息
`=~': invalid byte sequence in UTF-8 (ArgumentError)
完整代码如下。如果我在Rails控制台中运行它,它可以正常工作,但如果我使用ruby test.rb
运行它,它会给我第一个错误:
require 'smarter_csv'
headers = ["date_of_message", "timestamp_of_message", "sender", "phone_number", "message"]
path = '/path/'
Dir.glob("#{path}*.CSV").each do |file|
csv_text = File.read(file, :encoding => 'utf-16le')
File.open('/tmp/tmp_file', 'w') { |tmp_file| tmp_file.write(csv_text) }
puts 'made it here'
SmarterCSV.process('/tmp/tmp_file', {
:col_sep => "\t",
:force_simple_split => true,
:headers_in_file => false,
:user_provided_headers => headers
}).each do |row|
converted_row = {}
converted_row[:date_of_message] = row[:date_of_message][2..-2].to_date
converted_row[:timestamp] = row[:timestamp]
converted_row[:sender] = row[:sender][2..-2]
converted_row[:phone_number] = row[:phone_number][2..-2]
converted_row[:message] = row[:message][1..-2]
converted_row[:room] = file.gsub(path, '')
end
end
更新 - 2015年5月15日
最终,我决定将文件字符串编码为UTF-8,而不是深入了解SmarterCSV代码。 SmarterCSV代码中的第一个问题是它不允许用户在读取文件时指定二进制模式,但是在调整源代码来处理它之后,会弹出许多与编码相关的其他问题,其中很多都是相关的处理非UTF-8编码的文件上的各种参数。它可能是最简单的方法,但在将所有内容编码为SmarterCSV之前将其编码为UTF-8解决了我的问题。
答案 0 :(得分:1)
将binmode添加到File.read
来电。
File.read(file, :encoding => 'utf-16le', mode: "rb")
“b”二进制文件模式 抑制EOL&lt; - &gt; Windows上的CRLF转换。和 除非明确指出,否则将外部编码设置为ASCII-8BIT 指定。
参考:http://ruby-doc.org/core-2.0.0/IO.html#method-c-read
现在将正确的编码传递给SmarterCSV
SmarterCSV.process('/tmp/tmp_file', {
:file_encoding => "utf-16le", ...
<强>更新强>
发现smartercsv
不支持二进制模式。在OP尝试修改代码但没有成功之后,决定简单的解决方案是将输入转换为UTF-8
smartercsv
支持的meta_id post_id meta_key meta_value
1422 73 wpcf-milk 22
1423 73 wpcf-mw -7
。
答案 1 :(得分:0)
不幸的是,你正在使用'平面文件'的存储方式,而字符编码将成为两端的问题(阅读或写作)。
我建议使用类似str = str.force_encoding("UTF-8")
的内容,看看你是否可以使用它。