Question

I have been trying to get a (relatively) simple compression and decompression functionality working on any sort of object (images, csv files, docs etc) and have had no success whatsoever.

I have tried many things and currently I think this code is close to it (not my code) however I have been having trouble getting it to work.

Hoge.txt content:

blahblah123

Ruby deflate class titled rubyfiletest.rb:

require "zlib"

file_name = "hoge.txt"
compressed_file = File.open(file_name +".gz", "w+")

zd = Zlib::Deflate.new(Zlib::BEST_COMPRESSION, 15, Zlib::MAX_MEM_LEVEL, Zlib::HUFFMAN_ONLY)


compressed_file << zd.deflate(File.read(file_name))
compressed_file.close
zd.close

So with this code what it does is create a .gz file entitled hoge.txt.gz which generates this in the command prompt

rubyfiletest.rb:9:in `read': No such file or directory - hoge.txt (Errno::ENOEN)

Also if I try to open the newly created file with winrar/7zip it will give me this error:

The archive is either in unknown format or damaged.

Ruby inflate class titled rubyinflate.rb:

require 'zlib'

File.open('hoge.txt.gz', 'rb') do |compressed|
    File.open('hoge.txt', 'w') do |decompressed|
        gz = Zlib::GzipReader.new(compressed)
        result = gz.read
        decompressed.write(result)
        gz.close
    end
end

I am guessing the compression is not working correctly since I cannot even open the compressed file and have been having so many problems with this. I think it is worth while to mention I am new to ruby. I also would like to know if the way this is implemented would enable images and all types of files to be compressed/decompressed fine.

* Update *

I was getting the error for wrong path because hoge was saved as hoge.txt.txt (doh!) and it was looking for hoge.txt in that path. So now I changed the ruby compression code a little so that the output creates a valid gzip file as pointed out by Matthew T.

This is what it looks like now

require "zlib"

file_name = "hoge.txt"
compressed_file = File.open(file_name +".gz", "w+b")

zd = Zlib::GzipWriter.new(compressed_file)

zd << File.read(file_name)
compressed_file.close
zd.close

With this as the new rubyfiletest.rb class to decompress using GzipWriter I receive this error when I run this class:

rubyfiletest.rb:8 in 'write': closed stream (IOError)

This will still generate the .gz file (and I can now open it in winrar/7zip without any problems however it is empty, should contain 'blahblah123'). After I compress it and run the rubyinflate.rb I receive this error from rubyinflate.rb:

rubyinflate.rb:6 in 'read': unecpected end of file (Zlib::GzipFile::Error)

I think these errors may be causing the data to not be copied over? If I used an image would that data be copied over assuming this code worked?

Was it helpful?

Solution

Is your hoge.txt file in your current directory when you run your program? The big error warning indicating that the file cannot be found would be the first thing that I would try to resolve before assuming that the compression and decompression is not working. I think that you will find that the "compressed" file cannot be read because it is an empty file.


After you resolve your program's inability to find the hoge.txt file, you are still going to have problems with your output. Deflate does not create a gzip file; it only does the compression. There is more that goes into a gzip file than just the compressed data. There is also header and footer information. I would recommend that you use the GzipWriter class instead of the Deflate class.

require "zlib"

file_name = "hoge.txt"
compressed_file = File.open(file_name +".gz", "w+")

zd = Zlib::GzipWriter.new(compressed_file)

zd << File.read(file_name)
compressed_file.close

OTHER TIPS

Since you mentioned winrar, it sounds like you're on Windows. Once you get past finding hoge.txt, you will need a "w+b", not "w+" for the mode when writing the compressed data.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top