How to Read a File in Reverse Order

How to read a file in reverse order?

for line in reversed(open("filename").readlines()):
print line.rstrip()

And in Python 3:

for line in reversed(list(open("filename"))):
print(line.rstrip())

How to read a file in reverse order using C++

Yes, but you basically have to do it manually.

The basic algorithm is as follows:

  1. Seek to the end of the file with is.seekg(0, is.end)
  2. Determine the file size with is.tellg()
  3. Repeatedly seek backwards and read chunks of the file until you reach the front

How to read file in reverse order in python3.2 without reading the whole file to memory?

This is a function that does what you're looking for

def reverse_lines(filename, BUFSIZE=4096):
f = open(filename, "rb")
f.seek(0, 2)
p = f.tell()
remainder = ""
while True:
sz = min(BUFSIZE, p)
p -= sz
f.seek(p)
buf = f.read(sz) + remainder
if '\n' not in buf:
remainder = buf
else:
i = buf.index('\n')
for L in buf[i+1:].split("\n")[::-1]:
yield L
remainder = buf[:i]
if p == 0:
break
yield remainder

it works by reading a buffer from the end of the file (by default 4kb) and generating all the lines in it in reverse. It then moves back by 4k and does the same until the beginning of the file. The code may need to keep more than 4k in memory in case there are no linefeed in the section being processed (very long lines).

You can use the code as

for L in reverse_lines("my_big_file"):
... process L ...

How to read file from end to start (in reverse order) in Java?

As far as I understand, you try to read backwards line by line.
Suppose this is the file you try to read:

line1

line2

line3

And you want to write it to the output stream of the servlet as follows:

line3

line2

line1

Following code might be helpful in this case:

    List<String> tmp = new ArrayList<String>();

do {
ch = br.readLine();
tmp.add(ch);
out.print(ch+"<br/>");
} while (ch != null);

for(int i=tmp.size()-1;i>=0;i--) {
out.print(tmp.get(i)+"<br/>");
}

How to read lines from a file in python starting from the end

The general approach to this problem, reading a text file in reverse, line-wise, can be solved by at least three methods.

The general problem is that since each line can have a different length, you can't know beforehand where each line starts in the file, nor how many of them there are. This means you need to apply some logic to the problem.

General approach #1: Read the entire file into memory

With this approach, you simply read the entire file into memory, in some data structure that subsequently allows you to process the list of lines in reverse. A stack, a doubly linked list, or even an array can do this.

Pros: Really easy to implement (probably built into Python for all I know)

Cons: Uses a lot of memory, can take a while to read large files

General approach #2: Read the entire file, store position of lines

With this approach, you also read through the entire file once, but instead of storing the entire file (all the text) in memory, you only store the binary positions inside the file where each line started. You can store these positions in a similar data structure as the one storing the lines in the first approach.

Whever you want to read line X, you have to re-read the line from the file, starting at the position you stored for the start of that line.

Pros: Almost as easy to implement as the first approach

Cons: can take a while to read large files

General approach #3: Read the file in reverse, and "figure it out"

With this approach you will read the file block-wise or similar, from the end, and see where the ends are. You basically have a buffer, of say, 4096 bytes, and process the last line of that buffer. When your processing, which has to move one line at a time backward in that buffer, comes to the start of the buffer, you need to read another buffer worth of data, from the area before the first buffer you read, and continue processing.

This approach is generally more complicated, because you need to handle such things as lines being broken over two buffers, and long lines could even cover more than two buffers.

It is, however, the one that would require the least amount of memory, and for really large files, it might also be worth doing this to avoid reading through gigabytes of information first.

Pros: Uses little memory, does not require you to read the entire file first

Cons: Much hard to implement and get right for all corner cases


There are numerous links on the net that shows how to do the third approach:

  • ActiveState Recipe 120686 - Read a text file backwards
  • ActiveState Recipe 439045 - Read a text file backwards (yet another implementation)
  • Top4Download.com Script - Read a text file backwards

read file backwards (last line first)

It goes like this:

  1. Seek to one byte before the end of the file using fseek. There's no guarantee that the last line will have an EOL so the last byte doesn't really matter.
  2. Read one byte using fgetc.
  3. If that byte is an EOL then the last line is a single empty line and you have it.
  4. Use fseek again to go backwards two bytes and check that byte with fgetc.
  5. Repeat the above until you find an EOL. When you have an EOL, the file pointer will be at the beginning of the next (from the end) line.
  6. ...
  7. Profit.

Basically you have to keep doing (4) and (5) while keeping track of where you were when you found the beginning of a line so that you can seek back there before starting your scan for the beginning of the next line.

As long as you open your file in text mode you shouldn't have have to worry about multibyte EOLs on Windows (thanks for the reminder Mr. Lutz).

If you happen to be given a non-seekable input (such as a pipe), then you're out of luck unless you want to dump your input to a temporary file first.

So you can do it but it is rather ugly.

You could do pretty much the same thing using mmap and a pointer if you have mmap available and the "file" you're working with is mappable. The technique would be pretty much the same: start at the end and go backwards to find the end of the previous line.


Re: "I am the one creating this file. So, can I create in a way its in the reverse order? Is that possible?"

You'll run into the same sorts of problems but they'll be worse. Files in C are inherently sequential lists of bytes that start at the beginning and go to the end; you're trying to work against this fundamental property and going against the fundamentals is never fun.

Do you really need your data in a plain text file? Maybe you need text/plain as the final output but all the way through? You could store the data in an indexed binary file (possibly even an SQLite database) and then you'd only have to worry about keeping (or windowing) the index in memory and that's unlikely to be a problem (and if it is, use a "real" database); then, when you have all your lines, just reverse the index and away you go.

AWK read file in reverse order and print specified columns

In your command you were storing entire line($0) in array a, with little modification you can store required columns like below:

awk '{a[i++]=$1FS$3}END{for(j=i-1;j>=0;j--)print a[j];}'
C3 XVY
B2 CBZ
A1 ABC


Related Topics



Leave a reply



Submit