我在处理windows机器上生成的表格数据的文本文件时遇到了问题。我在Ruby1.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标志--我认为这应该可以抑制这种错误。
我已经转了好一阵子了。任何建议都将不胜感激。
谢谢!
编辑: 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现在,我只需要找到一种方法来自动确定要使用哪个分隔符。
发布于 2011-05-30 12:10:36
错误消息相当模糊,但我认为它不高兴的是,它在一行中发现了奇数个字节,因为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 \ngets读取到strip删除的第一个0x0a,所以读取的第一行是0x61 0x00 0x62 0x00,它愉快地接受并编码为0x61 0x62 - "ab“的UTF-8。然后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"。
发布于 2011-05-31 10:51:41
上面的答案是好的。您也可以在逐行处理之前将整个文件转换为UTF-8,但在大文件上可能会有更糟糕的流式传输行为。
https://stackoverflow.com/questions/6172095
复制相似问题