Ruby 1.8 Iconv UTF-16到UTF-8出现故障,并带有\000“;(Iconv::InvalidCharacter)
我在处理windows计算机上生成的表格数据的文本文件时遇到问题。 我在Ruby 1.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(
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,但在大文件上,这可能会有更糟糕的流行为