267

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

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

我认为将其转换为字符串就足够了,但是当我尝试像这样将其写回时...

newFile = File.open("test.tar.gz", "w")
newFile.write(contents)

不是同一个文件。做ls -l显示文件大小不同,尽管它们非常接近(打开文件会显示大部分内容完好无损)。我是否犯了一个小错误或完全不同(但可行)的方式来实现这一点?

4

9 回答 9

399

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

file = File.open("path-to-file.tar.gz", "rb")
contents = file.read

这将使您获得一个字符串中的整个文件。

之后,您可能想要file.close. 如果你不这样做,file在它被垃圾收集之前不会被关闭,所以它在打开时会稍微浪费系统资源。

于 2008-09-25T01:30:56.863 回答
247

如果您需要二进制模式,则需要以艰难的方式进行:

s = File.open(filename, 'rb') { |f| f.read }

如果没有,更短更甜的是:

s = IO.read(filename)
于 2008-11-07T05:24:54.170 回答
114

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

contents = File.open('path-to-file.tar.gz', 'rb') { |f| f.read }
于 2008-09-25T02:02:43.277 回答
17

一些打开/关闭安全性怎么样。

string = File.open('file.txt', 'rb') { |file| file.read }
于 2010-12-30T18:21:26.020 回答
16

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

无论如何,您可能会更好:

contents = File.read("e.tgz")
newFile = File.open("ee.tgz", "w")
newFile.write(contents)
于 2008-09-25T01:27:34.530 回答
15

Ruby 具有二进制读取功能

data = IO.binread(path/filaname)

或者如果低于 Ruby 1.9.2

data = IO.read(path/file)
于 2015-06-12T09:02:07.617 回答
6

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

你做这样的事情:

require 'base64'

file_contents = Base64.encode64(tar_file_data)

查看 Base64 Rubydocs以获得更好的想法。

于 2008-09-25T01:27:05.140 回答
1

Ruby 1.9+ 具有IO.binread(参见@bardzo 的回答)并且还支持将编码作为选项传递给IO.read

(请注意,在这两种情况下,它'BINARY'都是 . 的别名'ASCII-8BIT'

于 2021-04-28T18:26:12.003 回答
-1

如果您可以通过 Base64 对 tar 文件进行编码(并将其存储在纯文本文件中),您可以使用

File.open("my_tar.txt").each {|line| puts line}

或者

File.new("name_file.txt", "r").each {|line| puts line}

打印 cmd 中的每一行(文本)。

于 2014-11-24T11:31:26.653 回答