2011-12-22 62 views
4

我在更改Ruby 1.9.2p290中的文本文件上的编码时遇到问题。我收到UTF-8(ArgumentError)中的无效字节序列错误。问题(我认为)在于charset似乎是未知的事实。更改字符编码

在命令行,如果我做到以下几点:

$ file test.txt 

我得到:

Non-ISO extended-ASCII English text, with CRLF line terminators 

,或者,如果我这样做:

$ file -i test.txt 

我得到:

test.txt: text/plain; charset=unknown 

然而,在Ruby中,如果我这样做:

data = File.open("test.txt").read 

puts data.encoding.name 

puts data.valid_encoding? 

我得到:

UTF-8 
false 

这里是我的代码简单的代码片段:

data = File.open("test.txt").read 

data.encode!("UTF-8") 

data.each_line do |line| 

    newfile_data << line 

end 
+0

不该文件包含任何奇特的字符?你是如何创建文件/它保存为什么的? – deceze 2011-12-23 03:56:28

回答

2
data = IO.read("test.txt", :encoding => 'windows-1252') 
data = data.encode("UTF-8").gsub("\r\n", "\n") 
8

在Ruby 1.9的每流有2个与其相关的编码 - 外部和内部编码。 外部编码是从流中读取的文本的编码(在您的情况下,这是文件的编码)。内部编码是从文件读取的文本的所需编码。

如果您未设置流的外部/内部编码,则将使用该过程的默认外部/内部编码。如果未指定内部编码字符串从流中读取的标签(不转换)与外部编码(同String.force_encoding

很可能是因为

Encoding::default_external # => Encoding:UTF-8 
Encoding::default_internal # => nil 

而且你的文件在ASCII编码基于标准的字符编码,而不是UTF-8。 Ruby代码读取来自外部源的字节序列为UTF-8字符串。而且因为你的字符串包含Non-ISO extended-ASCII English textdata.valid_encoding? # => false

你需要设置的外部编码你的流向th e文件的编码。例如,如果你有CP 1251编码文本файл文件,那么你就需要用下面的代码来阅读:

data = File.open("test.txt", 'r:windows-1251').read  
puts data.encoding.name # => windows-1251 
puts data.valid_encoding? # => true 

甚至指定内部和外部编码:

data = File.open("test.txt", 'r:windows-1251:utf-8').read  
puts data.encoding.name # => utf-8 
puts data.valid_encoding? # => true