rubyrubyzip

ENOENT while trying to read a zipped file


I'm writing a simple program that takes an input string, splits it in words and saves it in it's memory. There's three methods -- to save a string into memory, to load from file and to load from zip archive. Here's the code:

require 'zip'

class Storage
  def initialize
    @storage = ''
  end

  def add(string)
    words = string.split ','
    words.each do |word|
      @storage << "#{word},"
    end
  end

  def load_from_file(filename)
    File.open filename, 'r' do |f|
      f.each { |line| add line }
    end
  end

  def load_from_zip(filename)
    Zip::File.open "#{filename}.zip" do |zipfile|
      zipfile.each { |entry| load_from_file entry.to_s }
    end
  end
end

While add and load_from_file methods work perfectly as I expect, load_from_zip returns me the following error each time I try to run it:

storage.rb:39:in `initialize': No such file or directory @ rb_sysopen - test.txt (Errno::ENOENT)

Although the file exists in my archive. I would appreciate any suggestion on what I'm doing wrong


Solution

  • Zip::File.open "#{filename}.zip"
    

    does not extract the zip file, it just opens it and shows what's inside. You cannot call

    File.open filename, 'r'
    

    since filename isn't in your filesystem, just inside the .zip file.

    You'll need to add a new method :

    require 'zip'
    
    class Storage
      def initialize
        @storage = ''
      end
    
      def add(string)
        words = string.split ','
        words.each do |word|
          @storage << "#{word},"
        end
      end
    
      def load_from_file(filename)
        File.open filename, 'r' do |f|
          f.each { |line| add line }
        end
      end
    
      def load_from_zip(filename)
        Zip::File.open "#{filename}.zip" do |zipfile|
          zipfile.each { |entry| load_from_zipped_file(zipfile,entry)}
        end
      end
    
      private
    
      def load_from_zipped_file(zipfile, entry)
        zipfile.read(entry).lines.each do |line|
          add line
        end
      end
    end
    
    s = Storage.new
    s.load_from_zip('test')