Я генерировал много файлов PDF в памяти, и я хочу сжать их в один zip-файл прежде, чем отправить ее как почтовое вложение. Я посмотрел на Rubyzip, и он не делает позволяет мне создавать zip-файл, не сохраняя его на диск (возможно, я неправ).
Есть ли какой-либо способ, которым я могу сжать их файл, не создавая временный файл?
Мне удалось найти две библиотеки RubyZip.
Библиотека Chilkat определенно позволяет создавать zip-файл в памяти вместо автоматической записи его на диск, как показано в следующих ссылках: Zip to Memory , Архивирование из данных в памяти
С другой стороны, файл на SourceForge может предоставлять возможность архивирования файла в памяти, но я не совсем уверен, так как я новичок в Ruby. Rubyzip SourceForge основан на java.util.zip
, что привело к тому, что у него появился класс ZipOutputStream
. Я не знаю, насколько хороша реализация rubyzip, но с реализацией java.util.zip
для OutputStream
можно установить значение ByteArrayOutputStream
, FileOutputStream
, FilterOutputStream
, ObjectOutputStream
, OutputStream
, PipedOutputStream
....
Если это верно для реализации rubyzip тогда следует использовать ZipOutputStream
для передачи типа ByteArrayOutputStream
, что приведет к его выводу в память.
Если его нет в rubyzip, я уверен, что вы всегда можете написать свою собственную реализацию и отправить ее для включения в rubyzip, поскольку это открытый исходный код.
Если вы работаете в Linux, и в зависимости от того, сколько у вас оперативной памяти и насколько велики ваши файлы, вы всегда можете использовать tmpfs (разделяемую память). Тогда дисковые методы rubyzip будут работать. http://www.mjmwired.net/kernel/Documentation/filesystems/tmpfs.txt
Ruby поставляется с очень удобной библиотекой StringIO
- ее можно использовать для использования String в качестве объекта ввода-вывода вывода или имитации чтения файла, поддерживаемого String.
Проблема здесь в том, что RubyZip не поддерживает прямое получение объекта ввода-вывода при создании Zip :: ZipOutputStream
, но если вы посмотрите на реализацию initialize
, и в зависимости от при вашей готовности поэкспериментировать, вы можете расширить класс и позволить ему принимать либо объект ввода-вывода, либо имя файла в конструкторе.