#!/usr/bin/env python # -*-mode: python; coding: iso-8859-1 -*- # # Copyright (c) Peter Astrand <astrand@cendio.se> import os import string class BackwardsReader: """Read a file line by line, backwards""" BLKSIZE = 4096 def readline(self): while 1: newline_pos = string.rfind(self.buf, "\n") pos = self.file.tell() if newline_pos != -1: # Found a newline line = self.buf[newline_pos+1:] self.buf = self.buf[:newline_pos] if pos != 0 or newline_pos != 0 or self.trailing_newline: line += "\n" return line else: if pos == 0: # Start-of-file return "" else: # Need to fill buffer toread = min(self.BLKSIZE, pos) self.file.seek(-toread, 1) self.buf = self.file.read(toread) + self.buf self.file.seek(-toread, 1) if pos - toread == 0: self.buf = "\n" + self.buf def __init__(self, file): self.file = file self.buf = "" self.file.seek(-1, 2) self.trailing_newline = 0 lastchar = self.file.read(1) if lastchar == "\n": self.trailing_newline = 1 self.file.seek(-1, 2) # Example usage br = BackwardsReader(open('bar')) while 1: line = br.readline() if not line: break print repr(line)