This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import os | |
def rblocks(f, blocksize=4096): | |
"""Read file as series of blocks from end of file to start. | |
The data itself is in normal order, only the order of the blocks is reversed. | |
ie. "hello world" -> ["ld","wor", "lo ", "hel"] | |
Note that the file must be opened in binary mode. | |
""" | |
if 'b' not in f.mode.lower(): | |
raise Exception("File must be opened using binary mode.") | |
size = os.stat(f.name).st_size | |
fullblocks, lastblock = divmod(size, blocksize) | |
# The first(end of file) block will be short, since this leaves | |
# the rest aligned on a blocksize boundary. This may be more | |
# efficient than having the last (first in file) block be short | |
f.seek(-lastblock,2) | |
yield f.read(lastblock) | |
for i in xrange(fullblocks-1,-1, -1): | |
f.seek(i * blocksize) | |
yield f.read(blocksize) | |
def rlines(f, keepends=False): | |
"""Iterate through the lines of a file in reverse order. | |
If keepends is true, line endings are kept as part of the line. | |
""" | |
buf = '' | |
for block in rblocks(f): | |
buf = block + buf | |
lines = buf.splitlines(keepends) | |
# Return all lines except the first (since may be partial) | |
if lines: | |
lines.reverse() | |
buf = lines.pop() # Last line becomes end of new first line. | |
for line in lines: | |
yield line | |
yield buf # First line. | |
file = open("example.txt", 'rb') | |
for line in rlines(file): | |
print line |
No comments:
Post a Comment