我无法处理在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
奇怪的是它读取并转换文件中的第一行没有问题。 我在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
现在我只需要找到一种方法来自动确定使用哪个分隔符。
答案 0 :(得分:6)
错误信息非常模糊,但我认为它在一条线路上找到奇数字节数这一事实感到不满,因为UTF-16中的每个字符都是两个(或偶尔为四个字符) )字节。我认为 的原因是你使用gets
- 文件中的行由UTF-16le换行符分隔,0x0a 0x00
,但是{{ 1}}正在拆分(gets
正在移除)strip
仅限。{/ p>
举例说明:假设文件包含
0x0a
以UTF-16le编码。那是
ab
cd
0x61 0x00 0x62 0x00 0x0a 0x00 0x63 0x00 0x64 0x00 0x0a 0x00
a b \n c d \n
读取gets
,0x0a
删除,因此读取的第一行是strip
,iconv很乐意接受并编码为UTF-8 0x61 0x00 0x62 0x00
- “ab”。 0x61 0x62
然后读取下一个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"
。
答案 1 :(得分:0)
上面的答案很好。您还可以在逐行处理之前将整个文件转换为UTF-8,但这可能会对大型文件产生更糟糕的流式传输行为。