在Ruby中将二进制文件读为字符串

Chr*_*nch 262 ruby string file-io

我需要一种简单的方法来获取tar文件并将其转换为字符串(反之亦然).有没有办法在Ruby中做到这一点?我最好的尝试是这样的:

file = File.open("path-to-file.tar.gz")
contents = ""
file.each {|line|
  contents << line
}
Run Code Online (Sandbox Code Playgroud)

我认为这足以将它转换为字符串,但是当我尝试将它写回来时......

newFile = File.open("test.tar.gz", "w")
newFile.write(contents)
Run Code Online (Sandbox Code Playgroud)

它不是同一个文件.做ls -l显示文件的大小不同,虽然它们非常接近(打开文件显示大部分内容完好无损).我正在制作一个小错误或完全不同(但可行)的方法来实现这一目标吗?

Dav*_*hme 398

首先,您应该将文件作为二进制文件打开.然后,您可以在一个命令中读取整个文件.

file = File.open("path-to-file.tar.gz", "rb")
contents = file.read
Run Code Online (Sandbox Code Playgroud)

这将以字符串形式获取整个文件.

在那之后,你可能想要file.close.如果不这样做,file在垃圾收集之前不会关闭,因此在打开时会略微浪费系统资源.

  • One-liner:File.open("path-to-file.tar.gz","rb").阅读 (93认同)
  • 二进制标志仅与Windows相关,这使文件描述符保持打开状态.File.read(...)更好. (22认同)
  • @ArianFaurtosh不,这是另一种读取文件的方法 - 这并不意味着它将被视为可执行的并且可以运行!对于简单的"阅读"方法而言,这将是一个可怕的副作用. (3认同)
  • 这应该在`begin {..open ..}确保{..close ..} end`块中完成 (2认同)
  • @David 你不能简单地做以下一行吗?`contents = File.binread('path-to-file.tar.gz')` 请参阅 [apidock](https://apidock.com/ruby/v2_6_3/IO/binread/class)。`File` 是 `IO` 的子类。 (2认同)

小智 242

如果你需要二进制模式,你需要以艰难的方式去做:

s = File.open(filename, 'rb') { |f| f.read }
Run Code Online (Sandbox Code Playgroud)

如果没有,更短更甜是:

s = IO.read(filename)
Run Code Online (Sandbox Code Playgroud)


Aar*_*nni 113

为避免文件打开,最好将块传递给File.open.这样,文件将在块执行后关闭.

contents = File.open('path-to-file.tar.gz', 'rb') { |f| f.read }
Run Code Online (Sandbox Code Playgroud)

  • 这是一个比David Nehme更好的答案,因为文件描述符是一个有限的系统资源,耗尽它们是一个很容易避免的常见问题. (10认同)

Pur*_*eas 17

在os x上这些对我来说都是一样的......这可能是Windows中额外的"\ r"吗?

在任何情况下,你可能会更好:

contents = File.read("e.tgz")
newFile = File.open("ee.tgz", "w")
newFile.write(contents)
Run Code Online (Sandbox Code Playgroud)


Ale*_*lex 17

一些开/关安全怎么样?

string = File.open('file.txt', 'rb') { |file| file.read }
Run Code Online (Sandbox Code Playgroud)

  • 这与2008年发布的[Aaron Hinni的回答](http://stackoverflow.com/a/131096/215168)相同(除了不使用OP的文件和变量名称)... (13认同)
  • File.open(){| file | 块}在块终止时自动关闭.http://ruby-doc.org/core-1.9.3/File.html#method-c-open (2认同)

小智 9

Ruby有二进制读取

data = IO.binread(path/filaname)
Run Code Online (Sandbox Code Playgroud)

或者如果小于Ruby 1.9.2

data = IO.read(path/file)
Run Code Online (Sandbox Code Playgroud)


小智 6

您可能可以在Base64中编码tar文件。Base 64将为您提供文件的纯ASCII表示形式,您可以将其存储在纯文本文件中。然后,您可以通过解码回文本来检索tar文件。

您可以执行以下操作:

require 'base64'

file_contents = Base64.encode64(tar_file_data)
Run Code Online (Sandbox Code Playgroud)

看一下Base64 Rubydocs以获得更好的主意。