我在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 :(得分:9)
在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 text
,因此您获得data.valid_encoding? # => false
。
您需要将流的外部编码设置为文件的编码。例如,如果您使用文本файл
的 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
答案 1 :(得分:3)
data = IO.read("test.txt", :encoding => 'windows-1252')
data = data.encode("UTF-8").gsub("\r\n", "\n")