class Zip::ZipOutputStream
ZipOutputStream is the basic class for writing zip files. It is possible to create a ZipOutputStream object directly, passing the zip file name to the constructor, but more often than not the ZipOutputStream will be obtained from a ZipFile (perhaps using the ZipFileSystem interface) object for a particular entry in the zip archive.
A ZipOutputStream inherits IOExtras::AbstractOutputStream in order to provide an IO-like interface for writing to a single zip entry. Beyond methods for mimicking an IO-object it contains the method #put_next_entry that closes the current entry and creates a new.
Please refer to ZipInputStream for example code.
java.util.zip.ZipOutputStream is the original inspiration for this class.
Attributes
Public Class Methods
Opens the indicated zip file. If a file with that name already exists it will be overwritten.
# File lib/zip/zip.rb, line 919 def initialize(fileName) super() @fileName = fileName @outputStream = File.new(@fileName, "wb") @entrySet = ZipEntrySet.new @compressor = NullCompressor.instance @closed = false @currentEntry = nil @comment = nil end
Same as initialize but if a block is passed the opened stream is passed to the block and closed when the block returns.
# File lib/zip/zip.rb, line 933 def ZipOutputStream.open(fileName) return new(fileName) unless block_given? zos = new(fileName) yield zos ensure zos.close if zos end
Public Instance Methods
Modeled after IO.<<
# File lib/zip/zip.rb, line 1029 def << (data) @compressor << data end
Closes the stream and writes the central directory to the zip file
# File lib/zip/zip.rb, line 942 def close return if @closed finalize_current_entry update_local_headers write_central_directory @outputStream.close @closed = true end
# File lib/zip/zip.rb, line 960 def copy_raw_entry(entry) entry = entry.dup raise ZipError, "zip stream is closed" if @closed raise ZipError, "entry is not a ZipEntry" if !entry.kind_of?(ZipEntry) finalize_current_entry @entrySet << entry src_pos = entry.local_entry_offset entry.write_local_entry(@outputStream) @compressor = NullCompressor.instance @outputStream << entry.get_raw_input_stream { |is| is.seek(src_pos, IO::SEEK_SET) is.read(entry.compressed_size) } @compressor = NullCompressor.instance @currentEntry = nil end
Closes the current entry and opens a new for writing. entry
can be a ZipEntry object or a string.
# File lib/zip/zip.rb, line 953 def put_next_entry(entry, level = Zlib::DEFAULT_COMPRESSION) raise ZipError, "zip stream is closed" if @closed newEntry = entry.kind_of?(ZipEntry) ? entry : ZipEntry.new(@fileName, entry.to_s) init_next_entry(newEntry, level) @currentEntry=newEntry end
Protected Instance Methods
# File lib/zip/zip.rb, line 1023 def finish @compressor.finish end
Private Instance Methods
# File lib/zip/zip.rb, line 979 def finalize_current_entry return unless @currentEntry finish @currentEntry.compressed_size = @outputStream.tell - @currentEntry.localHeaderOffset - @currentEntry.local_header_size @currentEntry.size = @compressor.size @currentEntry.crc = @compressor.crc @currentEntry = nil @compressor = NullCompressor.instance end
# File lib/zip/zip.rb, line 997 def get_compressor(entry, level) case entry.compression_method when ZipEntry::DEFLATED then Deflater.new(@outputStream, level) when ZipEntry::STORED then PassThruCompressor.new(@outputStream) else raise ZipCompressionMethodError, "Invalid compression method: '#{entry.compression_method}'" end end
# File lib/zip/zip.rb, line 990 def init_next_entry(entry, level = Zlib::DEFAULT_COMPRESSION) finalize_current_entry @entrySet << entry entry.write_local_entry(@outputStream) @compressor = get_compressor(entry, level) end
# File lib/zip/zip.rb, line 1006 def update_local_headers pos = @outputStream.tell @entrySet.each { |entry| @outputStream.pos = entry.localHeaderOffset entry.write_local_entry(@outputStream) } @outputStream.pos = pos end
# File lib/zip/zip.rb, line 1016 def write_central_directory cdir = ZipCentralDirectory.new(@entrySet, @comment) cdir.write_to_stream(@outputStream) end