class Archive::Tar::Minitar::Input
Wraps a Archive::Tar::Minitar::Reader
with convenience methods and wrapped stream management; Input
only works with random access data streams. See Input::new
for details.
Public Class Methods
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 Input#close
is called, the stream object wrapped will be closed.
# File lib/archive/tar/minitar.rb 673 def initialize(input) 674 if input.respond_to?(:read) 675 @io = input 676 else 677 @io = open(input, "rb") 678 end 679 @tarreader = Archive::Tar::Minitar::Reader.new(@io) 680 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 656 def self.open(input) 657 stream = Input.new(input) 658 return stream unless block_given? 659 660 begin 661 res = yield stream 662 ensure 663 stream.close 664 end 665 666 res 667 end
Public Instance Methods
Closes the Reader
object and the wrapped data stream.
# File lib/archive/tar/minitar.rb 771 def close 772 @io.close 773 @tarreader.close 774 end
Iterates through each entry and rewinds to the beginning of the stream when finished.
# File lib/archive/tar/minitar.rb 684 def each(&block) 685 @tarreader.each { |entry| yield entry } 686 ensure 687 @tarreader.rewind 688 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 709 def extract_entry(destdir, entry) # :yields action, name, stats: 710 stats = { 711 :current => 0, 712 :currinc => 0, 713 :entry => entry 714 } 715 716 if entry.directory? 717 dest = File.join(destdir, entry.full_name) 718 719 yield :dir, entry.full_name, stats if block_given? 720 721 if Archive::Tar::Minitar.dir?(dest) 722 begin 723 FileUtils.chmod(entry.mode, dest) 724 rescue Exception 725 nil 726 end 727 else 728 FileUtils.mkdir_p(dest, :mode => entry.mode) 729 FileUtils.chmod(entry.mode, dest) 730 end 731 732 fsync_dir(dest) 733 fsync_dir(File.join(dest, "..")) 734 return 735 else # it's a file 736 destdir = File.join(destdir, File.dirname(entry.full_name)) 737 FileUtils.mkdir_p(destdir, :mode => 0755) 738 739 destfile = File.join(destdir, File.basename(entry.full_name)) 740 FileUtils.chmod(0600, destfile) rescue nil # Errno::ENOENT 741 742 yield :file_start, entry.full_name, stats if block_given? 743 744 File.open(destfile, "wb", entry.mode) do |os| 745 loop do 746 data = entry.read(4096) 747 break unless data 748 749 stats[:currinc] = os.write(data) 750 stats[:current] += stats[:currinc] 751 752 yield :file_progress, entry.full_name, stats if block_given? 753 end 754 os.fsync 755 end 756 757 FileUtils.chmod(entry.mode, destfile) 758 fsync_dir(File.dirname(destfile)) 759 fsync_dir(File.join(File.dirname(destfile), "..")) 760 761 yield :file_done, entry.full_name, stats if block_given? 762 end 763 end
Returns the Reader
object for direct access.
# File lib/archive/tar/minitar.rb 766 def tar 767 @tarreader 768 end
Private Instance Methods
# File lib/archive/tar/minitar.rb 777 def fsync_dir(dirname) 778 # make sure this hits the disc 779 dir = open(dirname, 'rb') 780 dir.fsync 781 rescue # ignore IOError if it's an unpatched (old) Ruby 782 nil 783 ensure 784 dir.close if dir rescue nil 785 end