Wraps a Archive::Tar::Minitar::Reader with convenience methods and wrapped stream management; Input only works with random access data streams. See ::new for details.
Creates a new Input object. If input
is a stream object that responds to read), then it will simply be wrapped.
Otherwise, one will be created and opened using Kernel#open. When #close is called, the stream object
wrapped will be closed.
# File lib/archive/tar/minitar.rb, line 673 def initialize(input) if input.respond_to?(:read) @io = input else @io = open(input, "rb") end @tarreader = Archive::Tar::Minitar::Reader.new(@io) end
With no associated block, +Input::open+ is a synonym for +Input::new+. If the optional code block is given, it will be passed the new writer as an argument and the Input object will automatically be closed when the block terminates. In this instance, +Input::open+ returns the value of the block.
# File lib/archive/tar/minitar.rb, line 656 def self.open(input) stream = Input.new(input) return stream unless block_given? begin res = yield stream ensure stream.close end res end
Closes the Reader object and the wrapped data stream.
# File lib/archive/tar/minitar.rb, line 771 def close @io.close @tarreader.close end
Iterates through each entry and rewinds to the beginning of the stream when finished.
# File lib/archive/tar/minitar.rb, line 684 def each(&block) @tarreader.each { |entry| yield entry } ensure @tarreader.rewind end
Extracts the current entry
to destdir
. If a block
is provided, it yields an action
Symbol, the full name of the
file being extracted (name
), and a Hash of statistical
information (stats
).
The action
will be one of:
:dir
The entry
is a directory.
:file_start
The entry
is a file; the extract of the file is just
beginning.
:file_progress
Yielded every 4096 bytes during the extract of the entry
.
:file_done
Yielded when the entry
is completed.
The stats
hash contains the following keys:
:current
The current total number of bytes read in the entry
.
:currinc
The current number of bytes read in this read cycle.
:entry
The entry being extracted; this is a Reader::EntryStream, with all methods thereof.
# File lib/archive/tar/minitar.rb, line 709 def extract_entry(destdir, entry) # :yields action, name, stats: stats = { :current => 0, :currinc => 0, :entry => entry } if entry.directory? dest = File.join(destdir, entry.full_name) yield :dir, entry.full_name, stats if block_given? if Archive::Tar::Minitar.dir?(dest) begin FileUtils.chmod(entry.mode, dest) rescue Exception nil end else FileUtils.mkdir_p(dest, :mode => entry.mode) FileUtils.chmod(entry.mode, dest) end fsync_dir(dest) fsync_dir(File.join(dest, "..")) return else # it's a file destdir = File.join(destdir, File.dirname(entry.full_name)) FileUtils.mkdir_p(destdir, :mode => 0755) destfile = File.join(destdir, File.basename(entry.full_name)) FileUtils.chmod(0600, destfile) rescue nil # Errno::ENOENT yield :file_start, entry.full_name, stats if block_given? File.open(destfile, "wb", entry.mode) do |os| loop do data = entry.read(4096) break unless data stats[:currinc] = os.write(data) stats[:current] += stats[:currinc] yield :file_progress, entry.full_name, stats if block_given? end os.fsync end FileUtils.chmod(entry.mode, destfile) fsync_dir(File.dirname(destfile)) fsync_dir(File.join(File.dirname(destfile), "..")) yield :file_done, entry.full_name, stats if block_given? end end
Returns the Reader object for direct access.
# File lib/archive/tar/minitar.rb, line 766 def tar @tarreader end
# File lib/archive/tar/minitar.rb, line 777 def fsync_dir(dirname) # make sure this hits the disc dir = open(dirname, 'rb') dir.fsync rescue # ignore IOError if it's an unpatched (old) Ruby nil ensure dir.close if dir rescue nil end