class Zip::InputStream

InputStream is the basic class for reading zip entries in a zip file. It is possible to create a InputStream object directly, passing the zip file name to the constructor, but more often than not the InputStream will be obtained from a File (perhaps using the ZipFileSystem interface) object for a particular entry in the zip archive.

A InputStream inherits IOExtras::AbstractInputStream in order to provide an IO-like interface for reading from a single zip entry. Beyond methods for mimicking an IO-object it contains the method get_next_entry for iterating through the entries of an archive. get_next_entry returns a Entry object that describes the zip entry the InputStream is currently reading from.

Example that creates a zip archive with ZipOutputStream and reads it back again with a InputStream.

require 'zip'

Zip::OutputStream.open("my.zip") do |io|

  io.put_next_entry("first_entry.txt")
  io.write "Hello world!"

  io.put_next_entry("adir/first_entry.txt")
  io.write "Hello again!"
end

Zip::InputStream.open("my.zip") do |io|

  while (entry = io.get_next_entry)
    puts "Contents of #{entry.name}: '#{io.read}'"
  end
end

java.util.zip.ZipInputStream is the original inspiration for this class.

Public Class Methods

new(context, offset: 0, decrypter: nil) click to toggle source

Opens the indicated zip file. An exception is thrown if the specified offset in the specified filename is not a local zip entry header.

@param context [String||IO||StringIO] file path or IO/StringIO object @param offset [Integer] offset in the IO/StringIO

Calls superclass method
# File lib/zip/input_stream.rb, line 54
def initialize(context, offset: 0, decrypter: nil)
  super()
  @archive_io = get_io(context, offset)
  @decompressor = ::Zip::NullDecompressor
  @decrypter = decrypter
  @current_entry = nil
  @complete_entry = nil
end
open(filename_or_io, offset: 0, decrypter: nil) { |zio| ... } click to toggle source

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/input_stream.rb, line 128
def open(filename_or_io, offset: 0, decrypter: nil)
  zio = new(filename_or_io, offset: offset, decrypter: decrypter)
  return zio unless block_given?

  begin
    yield zio
  ensure
    zio.close if zio
  end
end

Public Instance Methods

close() click to toggle source

Close this InputStream. All further IO will raise an IOError.

# File lib/zip/input_stream.rb, line 64
def close
  @archive_io.close
end
get_next_entry() click to toggle source

Returns an Entry object and positions the stream at the beginning of the entry data. It is necessary to call this method on a newly created InputStream before reading from the first entry in the archive. Returns nil when there are no more entries.

# File lib/zip/input_stream.rb, line 72
def get_next_entry
  unless @current_entry.nil?
    raise StreamingError, @current_entry if @current_entry.incomplete?

    @archive_io.seek(@current_entry.next_header_offset, IO::SEEK_SET)
  end

  open_entry
end
rewind() click to toggle source

Rewinds the stream to the beginning of the current entry.

# File lib/zip/input_stream.rb, line 83
def rewind
  return if @current_entry.nil?

  @lineno = 0
  @pos    = 0
  @archive_io.seek(@current_entry.local_header_offset, IO::SEEK_SET)
  open_entry
end
size() click to toggle source

Returns the size of the current entry, or ‘nil` if there isn’t one.

# File lib/zip/input_stream.rb, line 118
def size
  return if @current_entry.nil?

  @current_entry.size
end
sysread(maxlen = nil, out_string = nil) click to toggle source

Modelled after IO#sysread.

Reads up to maxlen bytes from the stream; returns a string (either a new string or the given out_string). Its encoding is the unchanged encoding of out_string, if out_string is given; ASCII-8BIT, otherwise. Output contains maxlen bytes from the stream, if available; otherwise contains all available bytes, if any available; otherwise is an empty string.

This method should not be used with buffered input stream-reader methods, such as read, readline, gets.

# File lib/zip/input_stream.rb, line 103
def sysread(maxlen = nil, out_string = nil)
  # Remove the default value for maxlen for version 4.
  return (maxlen.nil? || maxlen.zero? ? '' : nil) if eof?

  output = produce_input(maxlen)

  if out_string.nil?
    output.force_encoding(Encoding::ASCII_8BIT)
  else
    encoding = out_string.encoding
    out_string.replace(output).force_encoding(encoding)
  end
end