Ruby GPGME — как шифровать большие файлы

У меня возникают трудности с шифрованием больших файлов (больше, чем доступная память) с помощью GPGME в Ruby.

#!/usr/bin/ruby
require 'gpgme'

def gpgfile(localfile)
  crypto = GPGME::Crypto.new
  filebasename = File.basename(localfile)
  filecripted = crypto.encrypt File.read(localfile), :recipients => "[email protected]", :always_trust => true
  File.open("#{localfile}.gpg", 'w') { |file| file.write(filecripted) }
end

gpgpfile("/home/largefile.data")

В этом случае я получил ошибку выделения памяти: "прочитано: не удалось выделить память (NoMemoryError)"

Кто-нибудь может объяснить мне, как читать исходный файл по частям (например, по 100 Мб) и записывать их, минуя шифрование?


person Marco Giusti    schedule 21.01.2016    source источник


Ответы (1)


Наиболее очевидная проблема заключается в том, что вы читаете весь файл в память с помощью File.read(localfile). Метод Crypto#encrypt примет объект ввода-вывода как его ввод, поэтому вместо File.read(localfile) (который возвращает содержимое файла в виде строки) вы можете передать ему объект File. Точно так же вы можете указать объект ввода-вывода в качестве опции :output, что позволит вам записывать вывод непосредственно в файл, а не в память:

def gpgfile(localfile)
  infile = File.open(localfile, 'r')
  outfile = File.open("#{localfile}.gpg", 'w')

  crypto = GPGME::Crypto.new    
  crypto.encrypt(infile, recipients: "[email protected]",
                         output: outfile,
                         always_trust: true)
ensure
  infile.close
  outfile.close
end

Я никогда не использовал ruby-gpgme, поэтому я не уверен на 100%, что это решит вашу проблему, поскольку это немного зависит от того, что делает ruby-gpgme за кулисами, но из документов и источника я заглянул в него. кажется разумно построенным драгоценным камнем, поэтому я предполагаю, что это поможет.

person Jordan Running    schedule 21.01.2016
comment
Я просто использую gpgme, и вот как я это делаю, поэтому он должен работать (хотя я использую блочную форму File.open) - person Frederick Cheung; 21.01.2016
comment
Уважаемый downvoter: Пожалуйста, оставьте комментарий, объясняющий причину вашего отрицательного голоса. Если мой ответ отсутствует, я был бы признателен за возможность улучшить его. - person Jordan Running; 21.01.2016
comment
Только что протестировано для моих целей, и это работает как шарм, большое спасибо! - person Marco Giusti; 22.01.2016