2008-09-25 2 views
256

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

Это ISN 't тот же файл. Выполнение ls -l показывает, что файлы имеют разные размеры, хотя они довольно близки (и открытие файла показывает большую часть содержимого неповрежденным). Есть ли небольшая ошибка, которую я делаю, или совершенно другой (но работоспособный) способ сделать это?

+3

Это сжатыми деготь файл (я надеюсь). Нет «линий». Pls разъясняет, чего вы пытаетесь достичь. – 2008-09-25 01:26:16

+0

Вы пытаетесь посмотреть сжатые данные или несжатый контент? – 2008-09-25 01:48:01

+0

поэтому символы в сжатом потоке данных будут иметь примерно 1 из 256 шансов приземления на «\ n», определяющем конец строки, и это нормально, если он не ожидает «\ r» тоже, см. Мой ответ ниже – Purfideas 2008-09-25 01:53:21

ответ

380

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

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

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

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

4

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

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

require 'base64' 

file_contents = Base64.encode64(tar_file_data) 

Есть взгляд на Base64 Rubydocs, чтобы получить лучшее представление.

+0

Отлично, похоже, это сработает! Я должен проверить это, если по какой-то причине чтение двоичного содержимого становится кислым. – 2008-09-25 02:02:55

16

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

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

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

`File.read (« e.txt »)` отлично работает для меня. – bean5 2015-09-24 17:50:36

+0

Это похоже на самое простое решение. – Dishcandanty 2016-05-25 19:27:20

113

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

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

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

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

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

s = IO.read(filename) 
17

как о некоторых открытой/закрыть безопасность.

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

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

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

или

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

напечатать каждый (текст) в cmd.

5

рубин имеют двоичный ЧТЕНИЕ

data = IO.binread(path/filaname) 

или менее Руби 1.9.2

data = IO.read(path/file) 
Смежные вопросы