Concatenate together multiple IO objects into a single, composite IO object for purposes of reading as a single stream.
Usage:
crio = CompositeReadIO.new(StringIO.new('one'), StringIO.new('two'), StringIO.new('three')) puts crio.read # => "onetwothree"
Create a new composite-read IO from the arguments, all of which should respond to read in a manner consistent with IO.
# File lib/composite_io.rb, line 18 def initialize(*ios) @ios = ios.flatten end
Read from the IO object, overlapping across underlying streams as necessary.
# File lib/composite_io.rb, line 23 def read(amount = nil, buf = nil) buffer = buf || '' done = if amount; nil; else ''; end partial_amount = amount parts = @ios.dup loop do result = done while !parts.empty? && (result = parts.first.read(partial_amount)) == done parts.shift end result.force_encoding("BINARY") if result.respond_to?(:force_encoding) buffer << result if result partial_amount -= result.length if partial_amount && result != done break if partial_amount && partial_amount <= 0 break if result == done end if buffer.length > 0 buffer else done end end
# File lib/composite_io.rb, line 51 def rewind @ios.each { |io| io.rewind } end