Method: ZipKit::Streamer#rollback!

Defined in:
lib/zip_kit/streamer.rb

#rollback!Integer

Removes the buffered local entry for the last file written. This can be used when rescuing from exceptions when you want to skip the file that failed writing into the ZIP from getting written out into the ZIP central directory. This is useful when, for example, you encounter errors retrieving the file that you want to place inside the ZIP from a remote storage location and some network exception gets raised. write_deflated_file and write_stored_file will rollback for you automatically. Of course it is not possible to remove the failed entry from the ZIP file entirely, as the data is likely already on the wire. However, excluding the entry from the central directory of the ZIP file will allow better-behaved ZIP unarchivers to extract the entries which did store correctly, provided they read the ZIP from the central directory and not straight-ahead.

Examples:

zip.add_stored_entry(filename: "data.bin", size: 4.megabytes, crc32: the_crc)
while chunk = remote.read(65*2048)
  zip << chunk
rescue Timeout::Error
  zip.rollback!
  # and proceed to the next file
end

Returns:

  • (Integer)

    position in the output stream / ZIP archive



498
499
500
501
502
503
504
505
506
507
508
509
# File 'lib/zip_kit/streamer.rb', line 498

def rollback!
  removed_entry = @files.pop
  return @out.tell unless removed_entry

  @path_set.clear
  @files.each do |e|
    @path_set.add_directory_or_file_path(e.filename) unless e.filler?
  end
  @files << Filler.new(@out.tell - removed_entry.local_header_offset)

  @out.tell
end