Чтение двоичного файла как строки в Ruby

Мне нужен простой способ взять 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 показывает, что файлы имеют разные размеры, хотя они довольно близки (и открытие файла показывает большую часть содержимого неповрежденным). Есть ли небольшая ошибка, которую я делаю или совершенно другой (но работоспособный) способ сделать это?

Ответ 1

Сначала вы должны открыть файл как двоичный файл. Затем вы можете прочитать весь файл в одной команде.

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

Это даст вам весь файл в строке.

После этого вы, вероятно, захотите file.close. Если вы этого не сделаете, file не будет закрыт, пока не будет собрано мусор, поэтому это будет небольшая трата системных ресурсов, пока он открыт.

Ответ 2

Если вам нужен двоичный режим, вам нужно сделать это сложным способом:

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

Если нет, короче и слаще:

s = IO.read(filename)

Ответ 3

Чтобы не оставлять файл открытым, лучше всего передать блок в File.open. Таким образом, файл будет закрыт после выполнения блока.

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

Ответ 4

on os x для меня такие же... возможно, это может быть лишнее "\ r" в окнах?

в любом случае вам может быть лучше:

contents = File.read("e.tgz")
newFile = File.open("ee.tgz", "w")
newFile.write(contents)

Ответ 5

как насчет какой-либо безопасности открытия/закрытия.

string = File.open('file.txt', 'rb') { |file| file.read }

Ответ 6

У Ruby есть двоичное чтение

data = IO.binread(path/filaname)

или меньше, чем Ruby 1.9.2

data = IO.read(path/file)

Ответ 7

Вероятно, вы можете закодировать tar файл в Base64. База 64 предоставит вам чистое ASCII-представление файла, который вы можете сохранить в текстовом файле. Затем вы можете получить tar файл, расшифровав текст.

Вы делаете что-то вроде:

require 'base64'

file_contents = Base64.encode64(tar_file_data)

Посмотрите на Base64 Rubydocs, чтобы получить лучшую идею.

Ответ 8

Если вы можете закодировать tar файл Base64 (и сохранить его в текстовом файле), вы можете использовать

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

или

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

для печати каждой (текстовой) строки в cmd.