Class: IOStreams::S3::Reader

Inherits:
Object
  • Object
show all
Defined in:
lib/io_streams/s3/reader.rb

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(region: nil, bucket:, key:) ⇒ Reader

Returns a new instance of Reader.



40
41
42
43
44
# File 'lib/io_streams/s3/reader.rb', line 40

def initialize(region: nil, bucket:, key:)
  s3      = region.nil? ? Aws::S3::Resource.new : Aws::S3::Resource.new(region: region)
  @object = s3.bucket(bucket).object(key)
  @buffer = []
end

Class Method Details

.open(uri = nil, bucket: nil, region: nil, key: nil, &block) ⇒ Object

Read from a AWS S3 file



5
6
7
8
9
10
11
12
13
14
15
# File 'lib/io_streams/s3/reader.rb', line 5

def self.open(uri = nil, bucket: nil, region: nil, key: nil, &block)
  options = uri.nil? ? args : parse_uri(uri).merge(args)
  s3      = region.nil? ? Aws::S3::Resource.new : Aws::S3::Resource.new(region: region)
  object  = s3.bucket(options[:bucket]).object(options[:key])

  IO.pipe do |read_io, write_io|
    object.get(response_target: write_io)
    write_io.close
    block.call(read_io)
  end
end

.open2(uri = nil, **args, &block) ⇒ Object



17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
# File 'lib/io_streams/s3/reader.rb', line 17

def self.open2(uri = nil, **args, &block)
  if !uri.nil? && IOStreams.reader_stream?(uri)
    raise(ArgumentError, 'S3 can only accept a URI, not an IO stream when reading.')
  end

  unless defined?(Aws::S3::Resource)
    begin
      require 'aws-sdk-s3'
    rescue LoadError => exc
      raise(LoadError, "Install gem 'aws-sdk-s3' to read and write AWS S3 files: #{exc.message}")
    end
  end

  options = uri.nil? ? args : parse_uri(uri).merge(args)

  begin
    io = new(**options)
    block.call(io)
  ensure
    io.close if io && (io.respond_to?(:closed?) && !io.closed?)
  end
end

Instance Method Details

#read(length = nil, outbuf = nil) ⇒ Object



46
47
48
49
50
51
52
53
54
55
56
# File 'lib/io_streams/s3/reader.rb', line 46

def read(length = nil, outbuf = nil)
  # Sufficient data already in the buffer
  return @buffer.slice!(0, length) if length && (length <= @buffer.length)

  # Fetch in chunks
  @object.get do |chunk|
    @buffer << chunk
    return @buffer.slice!(0, length) if length && (length <= @buffer.length)
  end
  @buffer if @buffer.size > 0
end