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 667 def initialize(input) 668 if input.respond_to?(:read) 669 @io = input 670 else 671 @io = open(input, "rb") 672 end 673 @tarreader = Archive::Tar::Minitar::Reader.new(@io) 674 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 650 def self.open(input) 651 stream = Input.new(input) 652 return stream unless block_given? 653 654 begin 655 res = yield stream 656 ensure 657 stream.close 658 end 659 660 res 661 end
Public Instance Methods
Closes the Reader
object and the wrapped data stream.
# File lib/archive/tar/minitar.rb 765 def close 766 @io.close 767 @tarreader.close 768 end
Iterates through each entry and rewinds to the beginning of the stream when finished.
# File lib/archive/tar/minitar.rb 678 def each(&block) 679 @tarreader.each { |entry| yield entry } 680 ensure 681 @tarreader.rewind 682 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 703 def extract_entry(destdir, entry) # :yields action, name, stats: 704 stats = { 705 :current => 0, 706 :currinc => 0, 707 :entry => entry 708 } 709 710 if entry.directory? 711 dest = File.join(destdir, entry.full_name) 712 713 yield :dir, entry.full_name, stats if block_given? 714 715 if Archive::Tar::Minitar.dir?(dest) 716 begin 717 FileUtils.chmod(entry.mode, dest) 718 rescue Exception 719 nil 720 end 721 else 722 FileUtils.mkdir_p(dest, :mode => entry.mode) 723 FileUtils.chmod(entry.mode, dest) 724 end 725 726 fsync_dir(dest) 727 fsync_dir(File.join(dest, "..")) 728 return 729 else # it's a file 730 destdir = File.join(destdir, File.dirname(entry.full_name)) 731 FileUtils.mkdir_p(destdir, :mode => 0755) 732 733 destfile = File.join(destdir, File.basename(entry.full_name)) 734 FileUtils.chmod(0600, destfile) rescue nil # Errno::ENOENT 735 736 yield :file_start, entry.full_name, stats if block_given? 737 738 File.open(destfile, "wb", entry.mode) do |os| 739 loop do 740 data = entry.read(4096) 741 break unless data 742 743 stats[:currinc] = os.write(data) 744 stats[:current] += stats[:currinc] 745 746 yield :file_progress, entry.full_name, stats if block_given? 747 end 748 os.fsync 749 end 750 751 FileUtils.chmod(entry.mode, destfile) 752 fsync_dir(File.dirname(destfile)) 753 fsync_dir(File.join(File.dirname(destfile), "..")) 754 755 yield :file_done, entry.full_name, stats if block_given? 756 end 757 end
Returns the Reader
object for direct access.
# File lib/archive/tar/minitar.rb 760 def tar 761 @tarreader 762 end
Private Instance Methods
# File lib/archive/tar/minitar.rb 771 def fsync_dir(dirname) 772 # make sure this hits the disc 773 dir = open(dirname, 'rb') 774 dir.fsync 775 rescue # ignore IOError if it's an unpatched (old) Ruby 776 nil 777 ensure 778 dir.close if dir rescue nil 779 end