Odczyt pliku binarnego jako ciąg znaków w Ruby

Potrzebuję łatwego sposobu, aby pobrać plik tar i przekonwertować go na ciąg znaków (i vice versa). Jest na to sposób w Ruby? Moja najlepsza próba była taka:

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

Myślałem, że to wystarczy, aby przekonwertować go na ciąg znaków, ale wtedy, gdy próbuję go odpisać w ten sposób...

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

To nie ten sam plik. Robienie ls -l pokazuje, że pliki są różnych rozmiarów, chociaż są dość blisko (a otwarcie pliku ujawnia większość zawartości nienaruszonej). Czy istnieje mały błąd, który popełniam, czy zupełnie inny (ale wykonalny) sposób na osiągnięcie tego?

Author: David Moles, 2008-09-25

8 answers

Najpierw należy otworzyć plik jako plik binarny. Następnie możesz odczytać cały plik w jednym poleceniu.

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

To da ci cały plik w ciągu znaków.

Po tym, prawdopodobnie chcesz file.close. Jeśli tego nie zrobisz, file nie zostanie zamknięta, dopóki nie zostanie usunięta, więc będzie to niewielkie marnowanie zasobów systemowych, gdy jest otwarta.

 398
Author: David Nehme,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-07-10 07:57:31

Jeśli potrzebujesz trybu binarnego, musisz to zrobić w trudny sposób:

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

Jeśli nie, krótszy i słodszy jest:

s = IO.read(filename)
 244
Author: ,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2008-11-07 05:24:54

Aby uniknąć pozostawienia pliku otwartego, najlepiej jest przekazać blok do pliku.otwórz. W ten sposób plik zostanie zamknięty po wykonaniu bloku.

contents = File.open('path-to-file.tar.gz', 'rb') { |f| f.read }
 114
Author: Aaron Hinni,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2008-09-25 02:02:43

Na os x są takie same dla mnie... czy to może być dodatkowe "\r " w windows?

W każdym razie może być lepiej z:

contents = File.read("e.tgz")
newFile = File.open("ee.tgz", "w")
newFile.write(contents)
 17
Author: Purfideas,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2008-09-25 01:27:34

Może jakieś zabezpieczenie przed otwarciem/zamknięciem.

string = File.open('file.txt', 'rb') { |file| file.read }
 17
Author: Alex,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-07-27 11:39:29

Ruby ma odczyt binarny

data = IO.binread(path/filaname)

Lub jeśli mniej niż Ruby 1.9.2

data = IO.read(path/file)
 10
Author: bardzo,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-06-12 09:02:07

Prawdopodobnie możesz zakodować plik tar w Base64. Base 64 daje czystą reprezentację ASCII pliku, który można przechowywać w zwykłym pliku tekstowym. Następnie możesz odzyskać plik tar, dekodując tekst z powrotem.

Robisz coś takiego:

require 'base64'

file_contents = Base64.encode64(tar_file_data)
W tej chwili możesz przypisać do domeny hosting, wybierając usługę dostosowaną do Twoich potrzeb:
 7
Author: ,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2008-09-25 01:27:05

Jeśli możesz zakodować plik tar za pomocą Base64 (i zapisać go w zwykłym pliku tekstowym), możesz użyć

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

Lub

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

Aby wydrukować każdy (tekst) wiersz w cmd.

 0
Author: Boris,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-05-14 16:09:43