I have a service that delivers zipped files over the web. The zip contains executable files for the Windows platform.
I'm using the RubyZip library to compress the file but the process corrupts the binary. At my local server we're using the zip command via a system call and it works fine.
The zip command is not available at Heroku, and I'm simply out of options.
I'm using this class:
require 'zip/zip'
# This is a simple example which uses rubyzip to
# recursively generate a zip file from the contents of
# a specified directory. The directory itself is not
# included in the archive, rather just its contents.
#
# Usage:
# directoryToZip = "/tmp/input"
# outputFile = "/tmp/out.zip"
# zf = ZipFileGenerator.new(directoryToZip, outputFile)
# zf.write()
class ZipFileGenerator
# Initialize with the directory to zip and the location of the output archive.
def initialize(inputDir, outputFile)
@inputDir = inputDir
@outputFile = outputFile
end
# Zip the input directory.
def write()
entries = Dir.entries(@inputDir); entries.delete("."); entries.delete("..")
io = Zip::ZipFile.open(@outputFile, Zip::ZipFile::CREATE);
writeEntries(entries, "", io)
io.close();
end
# A helper method to make the recursion work.
private
def writeEntries(entries, path, io)
entries.each { |e|
zipFilePath = path == "" ? e : File.join(path, e)
diskFilePath = File.join(@inputDir, zipFilePath)
puts "Deflating " + diskFilePath
if File.directory?(diskFilePath)
io.mkdir(zipFilePath)
subdir =Dir.entries(diskFilePath); subdir.delete("."); subdir.delete("..")
writeEntries(subdir, zipFilePath, io)
else
io.get_output_stream(zipFilePath) { |f| f.puts(File.open(diskFilePath, "rb").read())}
end
}
end
end