Class: BackwardsFileReader

Inherits:
Object
  • Object
show all
Defined in:
lib/backwards_file_reader.rb

Constant Summary collapse

DEFAULT_READ_SIZE =
4096

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(stream, read_size = DEFAULT_READ_SIZE) ⇒ BackwardsFileReader

Returns a new instance of BackwardsFileReader.



12
13
14
15
16
17
18
19
# File 'lib/backwards_file_reader.rb', line 12

def initialize(stream, read_size = DEFAULT_READ_SIZE)
  @stream = stream
  @stream.seek 0, IO::SEEK_END
  @pos = @stream.pos

  @read_size = [read_size, @pos].min
  @line_buffer = []
end

Class Method Details

.scan(stream, *init_args) ⇒ Object



2
3
4
5
6
7
8
# File 'lib/backwards_file_reader.rb', line 2

def self.scan(stream, *init_args)
  scanner = new(stream, *init_args)
  while line = scanner.readline
    break unless yield(line)
  end
  scanner.sync
end

Instance Method Details

#readlineObject



21
22
23
24
25
26
27
28
29
30
31
32
33
# File 'lib/backwards_file_reader.rb', line 21

def readline
  while @line_buffer.size < 2 && @pos > 0
    @read_size = [@read_size, @pos].min
    @pos -= @read_size
    @stream.seek(@pos, IO::SEEK_SET)

    @line_buffer[0] = "#{@stream.read(@read_size)}#{@line_buffer[0]}"
    @line_buffer[0] = @line_buffer[0].scan(%r{.*\n})
    @line_buffer.flatten!
  end

  @line_buffer.pop
end

#syncObject



35
36
37
38
39
# File 'lib/backwards_file_reader.rb', line 35

def sync
  offset = @read_size - @line_buffer.inject(0) { |n, l| n + l.size }
  @stream.seek(-offset, IO::SEEK_CUR) if offset != 0
  @stream
end