Class: Zip::InputStream

Inherits:
Object
  • Object
show all
Includes:
Zip::IOExtras::AbstractInputStream
Defined in:
lib/zip/input_stream.rb

Overview

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.

Constant Summary collapse

CHUNK_SIZE =
32_768

Instance Attribute Summary

Attributes included from Zip::IOExtras::AbstractInputStream

#lineno, #pos

Class Method Summary collapse

Instance Method Summary collapse

Methods included from Zip::IOExtras::AbstractInputStream

#each_line, #eof, #flush, #gets, #read, #readline, #readlines, #ungetc

Methods included from Zip::IOExtras::FakeIO

#kind_of?

Constructor Details

#initialize(context, dep_offset = 0, dep_decrypter = nil, offset: 0, decrypter: nil) ⇒ InputStream

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

Parameters:

  • context (String||IO||StringIO)

    file path or IO/StringIO object

  • offset (Integer) (defaults to: 0)

    offset in the IO/StringIO



52
53
54
55
56
57
58
59
60
61
62
63
64
# File 'lib/zip/input_stream.rb', line 52

def initialize(context, dep_offset = 0, dep_decrypter = nil, offset: 0, decrypter: nil)
  super()

  if !dep_offset.zero? || !dep_decrypter.nil?
    Zip.warn_about_v3_api('Zip::InputStream.new')
  end

  offset         = dep_offset if offset.zero?
  @archive_io    = get_io(context, offset)
  @decompressor  = ::Zip::NullDecompressor
  @decrypter     = decrypter || dep_decrypter || ::Zip::NullDecrypter.new
  @current_entry = nil
end

Class Method Details

.open(filename_or_io, dep_offset = 0, dep_decrypter = nil, offset: 0, decrypter: nil) ⇒ Object

Same as #initialize but if a block is passed the opened stream is passed to the block and closed when the block returns.



98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
# File 'lib/zip/input_stream.rb', line 98

def open(filename_or_io, dep_offset = 0, dep_decrypter = nil, offset: 0, decrypter: nil)
  if !dep_offset.zero? || !dep_decrypter.nil?
    Zip.warn_about_v3_api('Zip::InputStream.new')
  end

  offset = dep_offset if offset.zero?

  zio = new(filename_or_io, offset: offset, decrypter: decrypter || dep_decrypter)
  return zio unless block_given?

  begin
    yield zio
  ensure
    zio.close if zio
  end
end

.open_buffer(filename_or_io, offset = 0) ⇒ Object



115
116
117
118
119
# File 'lib/zip/input_stream.rb', line 115

def open_buffer(filename_or_io, offset = 0)
  Zip.warn_about_v3_api('Zip::InputStream.open_buffer')

  ::Zip::InputStream.open(filename_or_io, offset)
end

Instance Method Details

#closeObject



66
67
68
# File 'lib/zip/input_stream.rb', line 66

def close
  @archive_io.close
end

#get_next_entryObject

Returns a Entry object. 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.



74
75
76
77
# File 'lib/zip/input_stream.rb', line 74

def get_next_entry
  @archive_io.seek(@current_entry.next_header_offset, IO::SEEK_SET) if @current_entry
  open_entry
end

#rewindObject

Rewinds the stream to the beginning of the current entry



80
81
82
83
84
85
86
87
# File 'lib/zip/input_stream.rb', line 80

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

#sysread(length = nil, outbuf = '') ⇒ Object

Modeled after IO.sysread



90
91
92
# File 'lib/zip/input_stream.rb', line 90

def sysread(length = nil, outbuf = '')
  @decompressor.read(length, outbuf)
end