在 open-uri 模块的介绍中,文档是这样说的,
可以像打开文件一样打开 http、https 或 ftp URL
如果您对读取文件有所了解,那么您必须知道您尝试读取的文件的编码。您需要知道编码,以便告诉 ruby 如何读取文件(即每个字符将占用多少字节(或多少空间))。
在文档的第一个代码示例中,有这样的:
open("http://www.ruby-lang.org/en") {|f|
f.each_line {|line| p line}
p f.base_uri # <URI::HTTP:0x40e6ef2 URL:http://www.ruby-lang.org/en/>
p f.content_type # "text/html"
p f.charset # "iso-8859-1"
p f.content_encoding # []
p f.last_modified # Thu Dec 05 02:45:02 UTC 2002
}
因此,如果您不知道要读取的“文件”的编码,可以使用f.charset 获取编码。如果该编码与您的default external encoding 不同,您很可能会收到错误消息。您的 default external encoding 是 ruby 用于从外部源读取的编码。您可以像这样检查您的默认外部编码设置为:
默认的外部编码是从您的环境中提取的...有一个
看:
$ echo $LC_CTYPE
en_US.UTF-8
或
$ ruby -e 'puts Encoding.default_external.name'
UTF-8
http://graysoftinc.com/character-encodings/ruby-19s-three-default-encodings
在 Mac OSX 上,我实际上必须执行以下操作才能看到默认的外部编码:
$ echo $LANG
您可以使用Encoding.default_external=() 方法设置您的默认外部编码,因此您可能想尝试这样的事情:
open('some_url_here') do |f|
Encoding.default_external = f.charset
html = f.read
end
将 IO 对象设置为 binmode,就像您所做的那样,告诉 ruby 文件的编码是 BINARY(或 ruby 令人困惑的同义词 ASCII-8BIT),这意味着您告诉 ruby 文件中的每个字符占用一个字节。在您的情况下,您告诉 ruby 读取字符 U+00A0,其 UTF-8 表示占用两个字节 0xC2 0xA0,作为两个字符而不是一个字符,因此您已经消除了错误,但是您已经产生了两个垃圾字符而不是原始字符。