首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Ruby 1.8 Iconv UTF-16 to UTF-8失败,并显示"\000“(Iconv::InvalidCharacter)

Ruby 1.8 Iconv UTF-16 to UTF-8失败,并显示"\000“(Iconv::InvalidCharacter)
EN

Stack Overflow用户
提问于 2011-05-30 11:44:52
回答 2查看 2.5K关注 0票数 3

我在处理windows机器上生成的表格数据的文本文件时遇到了问题。我在Ruby1.8中工作。下面的代码在处理文件中的第二行时出现错误("\000“(Iconv::InvalidCharacter))。第一行已正确转换。

代码语言:javascript
复制
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解决方案解决了这个问题。谢谢。只需将代码更改为:

代码语言:javascript
复制
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

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

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2011-05-30 12:10:36

错误消息相当模糊,但我认为它不高兴的是,它在一行中发现了奇数个字节,因为UTF-16中的每个字符都是两个字节(有时是四个字节)。我认为这是因为您使用了gets--文件中的行用UTF-16le换行符分隔,换行符是0x0a 0x00,但是gets只拆分( strip删除) 0x0a

为了说明:假设文件包含以下内容

代码语言:javascript
复制
ab
cd

以UTF-16le编码。那是

代码语言:javascript
复制
0x61 0x00 0x62 0x00 0x0a 0x00 0x63 0x00 0x64 0x00 0x0a 0x00
    a         b         \n        c         d         \n

gets读取到strip删除的第一个0x0a,所以读取的第一行是0x61 0x00 0x62 0x00,它愉快地接受并编码为0x61 0x62 - "ab“的UTF-8。然后gets读取到下一个0x0astrip再次删除它,所以第二次line获得0x00 0x63 0x00 0x64 0x00时,现在一切都搞砸了-我们失去了一个字节的同步,有奇数个字节需要转换,iconv崩溃了,因为这与您要求它做的事情不兼容。

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

如果你使用的是windows文件,那么UTF-16le中的windows CRLF就是"\x0d\x00\x0a\x00"

票数 6
EN

Stack Overflow用户

发布于 2011-05-31 10:51:41

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

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/6172095

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档