Ruby 1.8 Iconv UTF-16到UTF-8失败,带有"\ 000"(Iconv :: InvalidCharacter)

NAD*_*NAD 3 ruby utf-8 utf-16 character-encoding iconv

我在处理在Windows机器上生成的列表数据的文本文件时遇到问题.我在Ruby 1.8工作.当从文件处理SECOND行时,以下给出错误("\ 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
Run Code Online (Sandbox Code Playgroud)

奇怪的是,它读取并转换文件中的第一行没有问题.我在Iconv构造函数中有// IGNORE标志 - 我认为这应该可以抑制这种错误.

我已经进入了一段时间.任何建议都将受到高度赞赏.

谢谢!

编辑:hobbs解决方案修复此问题.谢谢.只需将代码更改为:

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
Run Code Online (Sandbox Code Playgroud)

现在我只需要找到一种方法来自动确定哪个获取分隔符.

hob*_*bbs 6

错误信息非常模糊,但我认为它在一条线路上发现奇数个字节的事实并不令人满意,因为UTF-16中的每个字符都是两个(或偶尔四个)字节.我认为,理由你的使用gets-在你的文件中的行由UTF-16LE换行,这是分开0x0a 0x00的,但gets被分裂的(和strip被移除)0x0a只.

为了说明:假设文件包含

ab
cd
Run Code Online (Sandbox Code Playgroud)

以UTF-16le编码.那是

0x61 0x00 0x62 0x00 0x0a 0x00 0x63 0x00 0x64 0x00 0x0a 0x00
    a         b         \n        c         d         \n
Run Code Online (Sandbox Code Playgroud)

gets读取第一个0x0a,strip删除,所以第一行读取0x61 0x00 0x62 0x00,iconv愉快地接受并编码为UTF-8 0x61 0x62- "ab".gets然后读取到下一个0x0a,strip再次删除,所以第二次line得到0x00 0x63 0x00 0x64 0x00,现在一切都搞砸了 - 我们不同步一个字节,并且有一个奇数字节要转换,并且iconv爆炸,因为这与什么是不相容的你问它要做.

如果没有实际工作文件编码/解码层,我认为你想要的是将gets分隔符从"\n"("\x0a")更改为"\x0a\x00",放弃所有使用,strip因为它不是编码干净,print而是使用而不是puts为了不添加额外的行 -结束(因为你将转换你已经获得的那些).

如果您正在使用Windows文件,则UTF-16le中的Windows CRLF是"\x0d\x00\x0a\x00".