Ruby 1.8 Iconv UTF-16到UTF-8出现故障,并带有\000“;(Iconv::InvalidCharacter)

Ruby 1.8 Iconv UTF-16到UTF-8出现故障,并带有\000“;(Iconv::InvalidCharacter),ruby,utf-8,character-encoding,utf-16,iconv,Ruby,Utf 8,Character Encoding,Utf 16,Iconv,我在处理windows计算机上生成的表格数据的文本文件时遇到问题。 我在Ruby 1.8中工作。下面给出了在处理文件的第二行时出现的错误(“\000”(Iconv::InvalidCharacter))。第一行已正确转换 require 'iconv' conv = Iconv.new("UTF-8//IGNORE","UTF-16") infile = File.open(tabfile, "r") while (line = infile.gets) line = conv.iconv(

我在处理windows计算机上生成的表格数据的文本文件时遇到问题。 我在Ruby 1.8中工作。下面给出了在处理文件的第二行时出现的错误(“\000”(Iconv::InvalidCharacter))。第一行已正确转换

require 'iconv'
conv = Iconv.new("UTF-8//IGNORE","UTF-16")
infile = File.open(tabfile, "r")
while (line = infile.gets)
  line = conv.iconv(line.strip)  # FAILS HERE
  puts line
  # DO MORE STUFF HERE
end
奇怪的是,它读取和转换文件中的第一行没有问题。 我在Iconv构造函数中有//IGNORE标志——我认为这应该抑制这种错误

我兜圈子已经有一段时间了。如有任何建议,将不胜感激

谢谢

编辑: 霍布斯解决方案解决了这个问题。非常感谢。 只需将代码更改为:

require 'iconv'
conv = Iconv.new("UTF-8//IGNORE","UTF-16")
infile = File.open(tabfile, "r")
while (line = infile.gets("\x0a\x00"))
  line = conv.iconv(line.strip)  # NO LONGER FAILS HERE
  # DOES MORE STUFF HERE
end

现在,我只需要找到一种方法来自动确定使用哪个get separator。

错误消息非常模糊,但我认为它不高兴的是,它在一行中发现了奇数个字节,因为UTF-16中的每个字符都是两个(或偶尔是四个)字节。我认为这是因为您使用了
gets
——文件中的行由一个UTF-16le换行符分隔,它是
0x0a 0x00
,但是
gets
正在拆分(并且
strip
正在删除)
0x0a

举例说明:假设文件包含

ab
cd
以UTF-16le编码。那是

0x61 0x00 0x62 0x00 0x0a 0x00 0x63 0x00 0x64 0x00 0x0a 0x00
    a         b         \n        c         d         \n
获取
读取到第一个
0x0a
,该
条带
删除,因此读取的第一行是
0x61 0x00 0x62 0x00
,iconv愉快地接受该行,并将其编码到UTF-8,作为
0x61 0x62
-“ab”
获取
然后读取下一个
0x0a
,该
条带
再次删除,因此第二次
获取0x00 0x63 0x00 0x64 0x00现在一切都搞砸了-我们失去了一个字节的同步,有奇数个字节需要转换,而iconv爆炸是因为这与您要求它做的不兼容

如果没有实际的工作文件编码/解码层,我认为您需要将
获取的
分隔符从
“\n”
“\x0a”
)更改为
“\x0a\x00”
,放弃所有
条带的使用,因为它编码不干净,并使用
print
而不是
put
,这样您就不会添加额外的行尾(因为您将转换已有的行尾)


如果您正在使用windows文件,UTF-16le中的windows CRLF是
“\x0d\x00\x0a\x00”

以上答案很好。在逐行处理之前,您还可以将整个文件转换为UTF-8,但在大文件上,这可能会有更糟糕的流行为