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 => "info@address.com", :always_trust => true
  File.open("#{localfile}.gpg", 'w') { |file| file.write(filecripted) }
end

gpgpfile("/home/largefile.data")

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

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

1 ответ

Решение

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

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

  crypto = GPGME::Crypto.new    
  crypto.encrypt(infile, recipients: "info@address.com",
                         output: outfile,
                         always_trust: true)
ensure
  infile.close
  outfile.close
end

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

Другие вопросы по тегам