Question

I'm trying to gzip a file in ruby without having to write it to disk first. Currently I only know how to make it work by using Zlib::GzipWriter, but I'm really hoping that I can avoid that and keep it in-memory only.

I've tried this, with no success:

def self.make_gzip(data)
  gz = Zlib::GzipWriter.new(StringIO.new)
  gz << data
  string = gz.close.string
  StringIO.new(string, 'rb').read
end

Here is what happens when I test it out:

# Files
normal = File.new('chunk0.nbt')
gzipped = File.new('chunk0.nbt.gz')


# Try to create gzip in program
make_gzip normal
=> "\u001F\x8B\b\u0000\x8AJhS\u0000\u0003S\xB6q\xCB\xCCI\xB52\xA8000OK1L\xB2441J5\xB5\xB0\u0003\u0000\u0000\xB9\x91\xDD\u0018\u0000\u0000\u0000"

# Read from a gzip created with the gzip command
reader = Zlib::GzipReader.open gzipped
reader.read
"\u001F\x8B\b\u0000\u0000\u0000\u0000\u0000\u0000\u0000\xED]\xDBn\xDC\xC8\u0011%\x97N\xB82<\x9E\x89\xFF!\xFF!\xC9\xD6dFp\x80\u0005\xB2y\r\"\xEC\n\x89\xB0\xC6\xDAX+A./\xF94\xBF\u0006\xF1\x83>`\u0005\xCC\u000F\xC4\xF0\u000F.............(for 10,000 columns)
Was it helpful?

Solution

You're actually gzipping normal.to_s(which is something like "#<File:0x007f53c9b55b48>") in the following code.

# Files
normal = File.new('chunk0.nbt')

# Try to create gzip in program
make_gzip normal

You should read the content of the file, and make_gzip on the content:

make_gzip normal.read

As I commented, the make_gzip can be updated:

def self.make_gzip(data)
  gz = Zlib::GzipWriter.new(StringIO.new)
  gz << data
  gz.close.string
end
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top