module MultiZip::Backend::ArchiveZip
Constants
- BUFFER_SIZE
Public Instance Methods
extract_member(member_path, destination_path, options = {})
click to toggle source
# File lib/multi_zip/backend/archive_zip.rb, line 50 def extract_member(member_path, destination_path, options = {}) archive_operation do |zip| member = zip.find{|m| m.zip_path == member_path} if member && member.file? output_file = ::File.new(destination_path, 'wb') while chunk = member.file_data.read(BUFFER_SIZE) output_file.write chunk end output_file.close return destination_path else zip.close member_not_found!(member_path) end end end
list_members(prefix=nil, options={})
click to toggle source
# File lib/multi_zip/backend/archive_zip.rb, line 16 def list_members(prefix=nil, options={}) archive_operation do |zip| zip.entries.map(&:zip_path).select{|n| prefix ? n =~ /^#{prefix}/ : true }.sort end end
member_info(member_path, options = {})
click to toggle source
# File lib/multi_zip/backend/archive_zip.rb, line 101 def member_info(member_path, options = {}) archive_operation do |zip| member = zip.find{|m| m.zip_path == member_path} if member return { :path => member.zip_path, :size => member.expected_data_descriptor.uncompressed_size.to_i, :type => member.ftype, :original => member } else zip.close member_not_found!(member_path) end end end
read_member(member_path, options = {})
click to toggle source
# File lib/multi_zip/backend/archive_zip.rb, line 4 def read_member(member_path, options = {}) archive_operation do |zip| member = zip.find{|m| m.zip_path == member_path} if member && member.file? return member.file_data.read.to_s else zip.close member_not_found!(member_path) end end end
remove_member(member_path, options = {})
click to toggle source
# File lib/multi_zip/backend/archive_zip.rb, line 67 def remove_member(member_path, options = {}) remove_members([member_path], options) end
remove_members(member_paths, options = {})
click to toggle source
# File lib/multi_zip/backend/archive_zip.rb, line 71 def remove_members(member_paths, options = {}) archive_exists! member_paths.each do |member_path| exists!(member_path) end # archive-zip doesn't have the #remove_entry method any more, so we do # this in a really slow way: we dump the entire dir to the filesystem, # delete `member_path` and zip the whole thing up again. Dir.mktmpdir do |tmp_dir| Archive::Zip.extract(@filename, tmp_dir) member_paths.each do |member_path| FileUtils.rm("#{tmp_dir}/#{member_path}") end # create a tempfile and immediately delete it, we just want the name. tempfile = Tempfile.new(['multizip_temp', '.zip']) tempfile_path = tempfile.path tempfile.close tempfile.delete Archive::Zip.archive(tempfile_path, "#{tmp_dir}/.") FileUtils.mv(tempfile_path, @filename) end true end
write_member(member_path, member_contents, options = {})
click to toggle source
# File lib/multi_zip/backend/archive_zip.rb, line 24 def write_member(member_path, member_contents, options = {}) # archive/zip is really focused on adding content from the file system so # instead of hacking around with a non-public API that may change in the # future, we will just use tempfiles and let it read from disk like the # documentation says. tempfile = Tempfile.new('multizip_member') tempfile.write(member_contents) tempfile.close zip = Archive::Zip.new(@filename, :w) new_entry = Archive::Zip::Entry.from_file(tempfile.path, :zip_path => member_path) zip.add_entry(new_entry) # From the docs: The #close method must be called in order to save any # modifications to the archive. Due to limitations in the Ruby finalization # capabilities, the #close method is _not_ automatically called when this # object is garbage collected. Make sure to call #close when finished with # this object. zip.close true ensure if defined?(tempfile) tempfile.delete end end
Private Instance Methods
archive_operation(mode = :r) { |zip| ... }
click to toggle source
# File lib/multi_zip/backend/archive_zip.rb, line 120 def archive_operation(mode = :r) # mode is either :r or :w archive_exists! Archive::Zip.open(@filename, mode) do |zip| yield(zip) end rescue Archive::Zip::UnzipError => e raise MultiZip::InvalidArchiveError.new(@filename, e) end