使用Ruby自动以二进制格式打开文件

20

我正在使用Ruby 1.9打开多个文件并将它们复制到档案中。现在有一些二进制文件,但有些不是。由于Ruby 1.9不会自动将非二进制文件作为二进制文件打开,是否有一种方法可以自动打开它们? (例如“.class”是二进制文件,“.txt”则不是)

3个回答

39

实际上,Alex D之前的回答是不完整的。虽然Unix文件系统中确实没有"文本"模式,但 Ruby 在打开文件时会区分二进制和非二进制模式:

s = File.open('/tmp/test.jpg', 'r') { |io| io.read }
s.encoding
=> #<Encoding:UTF-8>

与之不同(注意"rb"

s = File.open('/tmp/test.jpg', 'rb') { |io| io.read }
s.encoding
=> #<Encoding:ASCII-8BIT>

根据文档所述,后一种方式会将外部编码设置为ASCII-8BIT,这告诉Ruby不要尝试以UTF-8解释结果。您可以通过显式地设置编码s.force_encoding('ASCII-8BIT')来实现相同的效果。如果您想将二进制读入字符串并移动它们(例如保存到数据库等),这非常重要。


18
自 Ruby 1.9.1 起,有一种专门用于二进制读取的方法(IO.binread),自 1.9.3 起也有了一个用于写入的方法(IO.binwrite)。
对于读取:
content = IO.binread(file)

写作技巧:

IO.binwrite(file, content)

由于 IOFile 的父类,你也可以使用下面这种方式,它可能更加表达清晰:

由于 IOFile 的父类,你也可以采用以下方式,这可能更加表达清晰:

content = File.binread(file)
File.binwrite(file, content)

2
是的,因为File类的父类是IO类。 - KARASZI István

1
在类Unix平台上,以“二进制”和“文本”模式打开文件没有区别。在Windows上,“文本”模式会将换行符转换为DOS格式,而“二进制”模式则不会。
除非您需要在Windows平台上进行换行符转换,否则请以“二进制”模式打开所有文件。以“二进制”模式读取文本文件不会有任何损害。
如果您真的想要区分,您将需要将File.extname(filename)与已知扩展名列表(如“.txt”和“.class”)匹配。

5
请注意,这个答案是错误的。Ruby 读取到一个字符串,并且从1.9版本开始,该字符串与一个编码相关联。请查看更高投票的答案获取详情并忽略本答案。如果Alex可以删除它就更好了。 - Michael Chaney
如果我只是删除它,现有的答案就没有意义了(“由AlexD...回答”)。最好先将此答案中提到的“b”标志对换行符转换的影响与其他答案中的信息合并。 - Alex D

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接