RobertoST
RobertoST

Reputation: 61

Python file.tell() giving wrong values

I am using Spyder 2.3.7 with Python 2.7.10 in Windows 7 64 bytes.

I want to read a file of text, and want to read the position in the file after reading a line; the main reason is for later be able to move back in the file after some search is done. Regardless of that, when I use the following code:

FileOrig = "testtext{Number}";
for index_file in range(1, 2):
    fileName = FileOrig.format(Number = str(index_file))

    ff = open(fileName, "rb")
    numline = 1;
    for line in ff: 
        numline = numline + 1;
        position = ff.tell();
        print(position);

    ff.close()

Where the content of file testtext1 is (this is just an example):

Overall accuracy
Overall accuracy
2.2603e+03
2.3179e+03
2.5265e+03
4.8463e+03
1.7547e+03
3.0143e+03
3.1387e+03


Overall accuracy
Overall accuracy
2.2414e+03
3.9409e+03
1.8902e+03
4.1157e+03


Overall accuracy
Overall accuracy
2.2275e+03
1.3579e+03
2.3712e+03
6.4970e+03
5.8891e+03



    SPLITBIB.STY     -- N. MARKEY <[email protected]>
                    v1.17 -- 2005/12/22

This package allows you to split a bibliography into several categories
and subcategories. It does not depend on BibTeX, and any bibliography
may be split and reordered.

split­bib – Split and re­order your bib­li­og­ra­phy

This pack­age en­ables you to split a bib­li­og­ra­phy into sev­eral cat­e­gories and sub­cat­e­gories. It does not de­pend on BibTeX: any bib­li­og­ra­phy may be split and re­ordered.

This produces me the very strange output:

916
916
916
916
916
916
916
916
916
916
916
916
916
916
916
916
916
916
916
916
916
916
916
916
916
916
916
916
916
916
916
916
916
916
916
916
916
916
916
916
916
916
916

What is wrong with the code above, nothing different if I use binary read or not.

Upvotes: 2

Views: 225

Answers (1)

falsetru
falsetru

Reputation: 369054

Mixing iteration-over-file and using file methods will not work because iteration involve using read-ahead buffer. Use file.readline instead to use file.tell:

...
while True:
    line = ff.readline()
    if not line:
        break
    numline = numline + 1
    position = ff.tell()
    print(position)
...

According to file.next documentation:

A file object is its own iterator, for example iter(f) returns f (unless f is closed). When a file is used as an iterator, typically in a for loop (for example, for line in f: print line.strip()), the next() method is called repeatedly. This method returns the next input line, or raises StopIteration when EOF is hit when the file is open for reading (behavior is undefined when the file is open for writing). In order to make a for loop the most efficient way of looping over the lines of a file (a very common operation), the next() method uses a hidden read-ahead buffer. As a consequence of using a read-ahead buffer, combining next() with other file methods (like readline()) does not work right. However, using seek() to reposition the file to an absolute position will flush the read-ahead buffer.

Upvotes: 2

Related Questions