2011-12-22 108 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