Я знаю, что есть несколько похожих вопросов об этой ошибке, и я пробовал много из них без везения. Проблема, с которой я сталкиваюсь, включает в себя байт \xA1
и бросает
ArgumentError: неверная последовательность байтов в UTF-8
Я пробовал следующее без успеха:
"\xA1".encode('UTF-8', :undef => :replace, :invalid => :replace,
:replace => "").sub('', '')
"\xA1".encode('UTF-8', :undef => :replace, :invalid => :replace,
:replace => "").force_encoding('UTF-8').sub('', '')
"\xA1".encode('UTF-8', :undef => :replace, :invalid => :replace,
:replace => "").encode('UTF-8').sub('', '')
Каждая строка вызывает ошибку для меня. Что я делаю неправильно?
UPDATE:
Вышеуказанные строки выходят из строя только в IRB. Тем не менее, я изменил свое приложение, чтобы кодировать строки CVS файла, используя тот же метод и аргументы String # encode, и я получаю ту же ошибку при чтении строки из файла (примечание: оно работает, если вы выполняете операции с одной и той же строкой без использования IO).
bad_line = "col1\tcol2\tbad\xa1"
bad_line.sub('', '') # does NOT fail
puts bad_line # => col1 col2 bad?
tmp = Tempfile.new 'foo' # write the line to a file to emulate real problem
tmp.puts bad_line
tmp.close
tmp2 = Tempfile.new 'bar'
begin
IO.foreach tmp.path do |line|
line.encode!('UTF-8', :undef => :replace, :invalid => :replace, :replace => "")
line.sub('', '') # fail: invalid byte sequence in UTF-8
tmp2.puts line
end
tmp2.close
# this would fail if the above error didn't halt execution
CSV.foreach(tmp2.path) do |row|
puts row.inspect # fail: invalid byte sequence in UTF-8
end
ensure
tmp.unlink
tmp2.close
tmp2.unlink
end