Читать бинарный файл как строку в Ruby - PullRequest
260 голосов
/ 25 сентября 2008

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

Ответы [ 8 ]

393 голосов
/ 25 сентября 2008

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

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

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

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

240 голосов
/ 07 ноября 2008

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

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

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

s = IO.read(filename)
112 голосов
/ 25 сентября 2008

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

contents = File.open('path-to-file.tar.gz', 'rb') { |f| f.read }
17 голосов
/ 25 сентября 2008

на OS X это то же самое для меня ... это может быть дополнительный "\ r" в Windows?

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

contents = File.read("e.tgz")
newFile = File.open("ee.tgz", "w")
newFile.write(contents)
16 голосов
/ 30 декабря 2010

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

string = File.open('file.txt', 'rb') { |file| file.read }
8 голосов
/ 12 июня 2015

Ruby имеет двоичное чтение

data = IO.binread(path/filaname)

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

data = IO.read(path/file)
5 голосов
/ 25 сентября 2008

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

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

require 'base64'

file_contents = Base64.encode64(tar_file_data)

Взгляните на Base64 Rubydocs , чтобы получить лучшую идею.

0 голосов
/ 24 ноября 2014

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

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

или

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

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...