class Zip::OutputStream
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.
Public Class Methods
Source
# File lib/zip/output_stream.rb, line 32 def initialize(file_name, stream: false, encrypter: nil, suppress_extra_fields: false) super() @file_name = file_name @output_stream = if stream iostream = Zip::RUNNING_ON_WINDOWS ? @file_name : @file_name.dup iostream.reopen(@file_name) iostream.rewind iostream else ::File.new(@file_name, 'wb') end @cdir = ::Zip::CentralDirectory.new @compressor = ::Zip::NullCompressor.instance @encrypter = encrypter || ::Zip::NullEncrypter.new @suppress_extra_fields = suppress_extra_fields @closed = false @current_entry = nil end
Opens the indicated zip file. If a file with that name already exists it will be overwritten.
Source
# File lib/zip/output_stream.rb, line 55 def open(file_name, encrypter: nil, suppress_extra_fields: false) return new(file_name) unless block_given? zos = new(file_name, stream: false, encrypter: encrypter, suppress_extra_fields: suppress_extra_fields) yield zos ensure zos.close if zos end
Same as initialize but if a block is passed the opened stream is passed to the block and closed when the block returns.
Source
# File lib/zip/output_stream.rb, line 66 def write_buffer(io = ::StringIO.new, encrypter: nil, suppress_extra_fields: false) io.binmode if io.respond_to?(:binmode) zos = new(io, stream: true, encrypter: encrypter, suppress_extra_fields: suppress_extra_fields) yield zos zos.close_buffer end
Same as open but writes to a filestream instead
Public Instance Methods
Source
# File lib/zip/output_stream.rb, line 199 def <<(data) @compressor << data self end
Modeled after IO.<<
Source
# File lib/zip/output_stream.rb, line 76 def close return if @closed finalize_current_entry update_local_headers @cdir.write_to_stream(@output_stream, suppress_extra_fields: @suppress_extra_fields) @output_stream.close @closed = true end
Closes the stream and writes the central directory to the zip file
Source
# File lib/zip/output_stream.rb, line 87 def close_buffer return @output_stream if @closed finalize_current_entry update_local_headers @cdir.write_to_stream(@output_stream, suppress_extra_fields: @suppress_extra_fields) @closed = true @output_stream.flush @output_stream end
Closes the stream and writes the central directory to the zip file
Source
# File lib/zip/output_stream.rb, line 100 def put_next_entry( entry_name, comment = '', extra = ExtraField.new, compression_method = Entry::DEFLATED, level = Zip.default_compression ) raise Error, 'zip stream is closed' if @closed new_entry = if entry_name.kind_of?(Entry) || entry_name.kind_of?(StreamableStream) entry_name else Entry.new( @file_name, entry_name.to_s, comment: comment, extra: extra, compression_method: compression_method, compression_level: level ) end init_next_entry(new_entry) @current_entry = new_entry end
Closes the current entry and opens a new for writing. entry can be a ZipEntry object or a string.
Private Instance Methods
Source
# File lib/zip/output_stream.rb, line 141 def finalize_current_entry return unless @current_entry finish @current_entry.compressed_size = @output_stream.tell - @current_entry.local_header_offset - @current_entry.calculate_local_header_size @current_entry.size = @compressor.size @current_entry.crc = @compressor.crc @output_stream << @encrypter.data_descriptor( @current_entry.crc, @current_entry.compressed_size, @current_entry.size ) @current_entry.gp_flags |= @encrypter.gp_flags @current_entry = nil @compressor = ::Zip::NullCompressor.instance end
Source
# File lib/zip/output_stream.rb, line 169 def get_compressor(entry) case entry.compression_method when Entry::DEFLATED ::Zip::Deflater.new(@output_stream, entry.compression_level, @encrypter) when Entry::STORED ::Zip::PassThruCompressor.new(@output_stream) else raise ::Zip::CompressionMethodError, entry.compression_method end end
Source
# File lib/zip/output_stream.rb, line 160 def init_next_entry(entry) finalize_current_entry @cdir << entry entry.write_local_entry(@output_stream, suppress_extra_fields: @suppress_extra_fields) @encrypter.reset! @output_stream << @encrypter.header(entry.mtime) @compressor = get_compressor(entry) end
Source
# File lib/zip/output_stream.rb, line 180 def update_local_headers pos = @output_stream.pos @cdir.each do |entry| @output_stream.pos = entry.local_header_offset entry.write_local_entry(@output_stream, suppress_extra_fields: @suppress_extra_fields, rewrite: true) end @output_stream.pos = pos end