Class: IO::Tail::File
Direct Known Subclasses
Instance Attribute Summary collapse
-
#_file ⇒ Object
readonly
Returns the value of attribute _file.
Attributes inherited from Tailable
#break_if_eof, #default_bufsize, #interval, #max_interval, #reopen_deleted, #reopen_suspicious, #return_if_eof, #suspicious_interval
Instance Method Summary collapse
-
#backward(n = 0, bufsize = nil) ⇒ Object
Rewind the last
nlines of this file, starting from the end. - #close ⇒ Object
-
#forward(n = 0) ⇒ Object
Skip the first
nlines of this file. -
#handle_EOFError ⇒ Object
On EOF, we seek to position 0 Next read will reopen the file if it has changed.
- #handle_ReopenException(ex, &block) ⇒ Object
-
#initialize(file_or_filename = nil) ⇒ File
constructor
A new instance of File.
- #path ⇒ Object
- #puts(o) ⇒ Object
- #readline ⇒ Object
- #reopen_tailable(mode) ⇒ Object
- #restat ⇒ Object
Methods inherited from Tailable
Constructor Details
#initialize(file_or_filename = nil) ⇒ File
Returns a new instance of File.
230 231 232 233 234 235 236 237 238 |
# File 'lib/io/tail.rb', line 230 def initialize(file_or_filename = nil) super() if file_or_filename.is_a?(String) @_file = ::File.new(file_or_filename, 'rb') elsif file_or_filename.is_a?(::File) @_file = file_or_filename end self._file.seek(0, ::File::SEEK_END) end |
Instance Attribute Details
#_file ⇒ Object (readonly)
Returns the value of attribute _file.
228 229 230 |
# File 'lib/io/tail.rb', line 228 def _file @_file end |
Instance Method Details
#backward(n = 0, bufsize = nil) ⇒ Object
Rewind the last n lines of this file, starting from the end. The default is to start tailing directly from the end of the file.
The additional argument bufsize is used to determine the buffer size that is used to step through the file backwards. It defaults to the block size of the filesystem this file belongs to or 8192 bytes if this cannot be determined.
271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 |
# File 'lib/io/tail.rb', line 271 def backward(n = 0, bufsize = nil) if n <= 0 self._file.seek(0, ::File::SEEK_END) return self end bufsize ||= default_bufsize || self._file.stat.blksize || 8192 size = self._file.stat.size begin if bufsize < size self._file.seek(0, ::File::SEEK_END) while n > 0 and self._file.tell > 0 do start = self._file.tell self._file.seek(-bufsize, ::File::SEEK_CUR) buffer = self._file.read(bufsize) n -= buffer.count("\n") self._file.seek(-bufsize, ::File::SEEK_CUR) end else self._file.seek(0, ::File::SEEK_SET) buffer = self._file.read(size) n -= buffer.count("\n") self._file.seek(0, ::File::SEEK_SET) end rescue Errno::EINVAL size = self._file.tell retry end pos = -1 while n < 0 # forward if we are too far back pos = buffer.index("\n", pos + 1) n += 1 end self._file.seek(pos + 1, ::File::SEEK_CUR) self end |
#close ⇒ Object
240 241 242 |
# File 'lib/io/tail.rb', line 240 def close self._file.close end |
#forward(n = 0) ⇒ Object
Skip the first n lines of this file. The default is to don’t skip any lines at all and start at the beginning of this file.
254 255 256 257 258 259 260 261 |
# File 'lib/io/tail.rb', line 254 def forward(n = 0) self._file.seek(0, ::File::SEEK_SET) while n > 0 and not self._file.eof? self._file.readline n -= 1 end self end |
#handle_EOFError ⇒ Object
On EOF, we seek to position 0 Next read will reopen the file if it has changed
309 310 311 312 |
# File 'lib/io/tail.rb', line 309 def handle_EOFError self._file.seek(0, ::File::SEEK_CUR) super end |
#handle_ReopenException(ex, &block) ⇒ Object
314 315 316 317 318 319 320 321 322 |
# File 'lib/io/tail.rb', line 314 def handle_ReopenException(ex, &block) # Something wrong with the file, attempt to go until its end # or at least to read n lines and then proceed to reopening until self._file.eof? || @n == 0 block.call self._file.readline @n -= 1 if @n end super end |
#path ⇒ Object
244 245 246 |
# File 'lib/io/tail.rb', line 244 def path self._file.path end |
#puts(o) ⇒ Object
248 249 250 |
# File 'lib/io/tail.rb', line 248 def puts o self._file.puts o end |
#readline ⇒ Object
324 325 326 |
# File 'lib/io/tail.rb', line 324 def readline self._file.readline end |
#reopen_tailable(mode) ⇒ Object
346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 |
# File 'lib/io/tail.rb', line 346 def reopen_tailable(mode) $DEBUG and $stdout.print "Reopening '#{path}', mode = #{mode}.\n" @no_read = 0 self._file.reopen(::File.new(self._file.path, 'rb')) if mode == :bottom backward end rescue Errno::ESTALE, Errno::ENOENT if @reopen_deleted sleep @max_interval retry else raise DeletedException end end |
#restat ⇒ Object
328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 |
# File 'lib/io/tail.rb', line 328 def restat stat = ::File.stat(self._file.path) if @stat if stat.ino != @stat.ino or stat.dev != @stat.dev @stat = nil raise ReopenException.new(:top) end if stat.size < @stat.size @stat = nil raise ReopenException.new(:top) end else @stat = stat end rescue Errno::ENOENT, Errno::ESTALE raise ReopenException end |