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, 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


54
55
56
57
58
59
60
61
# 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 || ::Zip::NullDecrypter.new
  @current_entry = nil
  @complete_entry = nil
end

Class Method Details

.open(filename_or_io, 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.


112
113
114
115
116
117
118
119
120
121
# File 'lib/zip/input_stream.rb', line 112

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

.open_buffer(filename_or_io, offset: 0) ⇒ Object


123
124
125
126
# File 'lib/zip/input_stream.rb', line 123

def open_buffer(filename_or_io, offset: 0)
  warn 'open_buffer is deprecated!!! Use open instead!'
  ::Zip::InputStream.open(filename_or_io, offset: offset)
end

Instance Method Details

#closeObject


63
64
65
# File 'lib/zip/input_stream.rb', line 63

def close
  @archive_io.close
end

#get_next_entryObject

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.


71
72
73
74
75
76
77
78
79
80
81
82
83
84
# File 'lib/zip/input_stream.rb', line 71

def get_next_entry
  unless @current_entry.nil?
    if @current_entry.incomplete?
      raise GPFBit3Error,
            'It is not possible to get complete info from the local ' \
            'header to extract this entry (GP flags bit 3 is set). ' \
            'Please use `Zip::File` instead of `Zip::InputStream`.'
    end

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

  open_entry
end

#rewindObject

Rewinds the stream to the beginning of the current entry


87
88
89
90
91
92
93
94
# File 'lib/zip/input_stream.rb', line 87

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

#sizeObject

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


102
103
104
105
106
# File 'lib/zip/input_stream.rb', line 102

def size
  return if @current_entry.nil?

  @current_entry.size
end

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

Modeled after IO.sysread


97
98
99
# File 'lib/zip/input_stream.rb', line 97

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