tags:

views:

264

answers:

3

I have generated many pdf files in memory and I want to compress them into one zip file before sending it as a email attachment. I have looked at Rubyzip and it does not allows me to create a zip file without saving it to disk (maybe I am wrong).

Is there any way I can compress those file without creating a temp file ?

A: 

There are two RubyZip libraries that I was able to find.

  1. Chilkat's Ruby Zip Library
  2. rubyzip on Sourforge

Chilkat's library definitely allows one to create a zip file in memory instead of writing it to disk automatically as seen in these links: Zip to Memory, Zip from in memory data

The one on sourceforge, on the other hand, may provide an option of zipping a file in memory but I'm not entirely certain since I'm very new to ruby. The sourceforge rubyzip is based off java.util.zip which has led to it having a class called ZipOutputStream. I don't know how good the rubyzip implementation is, but with java.util.zip implementation the OutputStream can be set to ByteArrayOutputStream, FileOutputStream, FilterOutputStream, ObjectOutputStream, OutputStream, PipedOutputStream...

If that holds true for the rubyzip implementation then it should be a matter of using ZipOutputStream to pass in a ByteArrayOutputStream of sorts which would result in it being output to memory.

If it doesn't exist in rubyzip, then I'm sure you could always write your own implementation and submit it for inclusion in rubyzip seeing as it is opensource.

mezoid
The one I was referring was the gem: http://rubygems.org/gems/rubyzipI don't want to use the Chilkat library since there it's not open source.
Martinos
I won't downrate this, but I didn't find anywhere a comment like "no, the standard Ruby ZIP classes can NOT do this". I believe you should have started with it.
dimitko
In fact the ZipOutputStream new method takes a file name as argument, I didn't find any way to pass an IO object.
Martinos
dimitko, there are no standard ruby library for zip. I have checked rubyzip but it seems that there is nothing for doing what I want.
Martinos
@flutedemetan, like I said above, if it doesn't exist then you'll either need to use another library or make your own addition to the rubyzip open source project.
mezoid
A: 

If you're on Linux, and depending upon how much RAM you have, and how large your files are, you could always use tmpfs (shared memory). Then, the rubyzip disk-based methods will work. http://www.mjmwired.net/kernel/Documentation/filesystems/tmpfs.txt

Noah
+2  A: 

Ruby comes with a very convenient StringIO library - this can be used for using a String as output IO object or faking reading a file backed by a String.

The challenge here is that RubyZip does not support directly taking an IO object when creating a Zip::ZipOutputStream, but if you look at the implementation of the initialize, and depending on your willingness to experiment, you may be able to extend the class and allow it to take either an IO object or a file name in the constructor.

laust.rud