How to read a file in reverse order?
A correct, efficient answer written as a generator.
import osdef reverse_readline(filename, buf_size=8192): """A generator that returns the lines of a file in reverse order""" with open(filename) as fh: segment = None offset = 0 fh.seek(0, os.SEEK_END) file_size = remaining_size = fh.tell() while remaining_size > 0: offset = min(file_size, offset + buf_size) fh.seek(file_size - offset) buffer = fh.read(min(remaining_size, buf_size)) remaining_size -= buf_size lines = buffer.split('\n') # The first line of the buffer is probably not a complete line so # we'll save it and append it to the last line of the next buffer # we read if segment is not None: # If the previous chunk starts right from the beginning of line # do not concat the segment to the last line of new chunk. # Instead, yield the segment first if buffer[-1] != '\n': lines[-1] += segment else: yield segment segment = lines[0] for index in range(len(lines) - 1, 0, -1): if lines[index]: yield lines[index] # Don't yield None if the file was empty if segment is not None: yield segment
You can also use python module file_read_backwards
.
After installing it, via pip install file_read_backwards
(v1.2.1), you can read the entire file backwards (line-wise) in a memory efficient manner via:
#!/usr/bin/env python2.7from file_read_backwards import FileReadBackwardswith FileReadBackwards("/path/to/file", encoding="utf-8") as frb: for l in frb: print l
It supports "utf-8","latin-1", and "ascii" encodings.
Support is also available for python3. Further documentation can be found at http://file-read-backwards.readthedocs.io/en/latest/readme.html