改变字符编码

thi*_*ton 5 ruby character-encoding

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

如果我执行以下操作,请从命令行:

$ file test.txt
Run Code Online (Sandbox Code Playgroud)

我明白了:

Non-ISO extended-ASCII English text, with CRLF line terminators
Run Code Online (Sandbox Code Playgroud)

或者,如果我这样做:

$ file -i test.txt 
Run Code Online (Sandbox Code Playgroud)

我明白了:

test.txt: text/plain; charset=unknown
Run Code Online (Sandbox Code Playgroud)

但是,如果我这样做,在Ruby中:

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

puts data.encoding.name

puts data.valid_encoding?
Run Code Online (Sandbox Code Playgroud)

我明白了:

UTF-8
false
Run Code Online (Sandbox Code Playgroud)

这是我的代码的简化片段:

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

data.encode!("UTF-8")

data.each_line do |line|

  newfile_data << line

end
Run Code Online (Sandbox Code Playgroud)

Ali*_*kau 9

在ruby 1.9中,每个流都有2个与之关联的编码 - 外部和内部编码.外部编码是您从流中读取的文本的编码(在您的情况下,这是文件的编码).内部编码是从文件读取的文本的所需编码.

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

你最有可能

Encoding::default_external # => Encoding:UTF-8
Encoding::default_internal # => nil
Run Code Online (Sandbox Code Playgroud)

并且您的文件使用基于ASCII的标准字符编码进行编码,而不是UTF-8.您的Ruby代码从外部源读取字节序列为UTF-8字符串.因为你的字符串包含了Non-ISO extended-ASCII English textdata.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
Run Code Online (Sandbox Code Playgroud)

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

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


sun*_*ity 3

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