Seek and Tell

We can move around our files and perfom tasks wherever we are in the file. Although handy, it’s also a bit tricky. Let’s take a look.

What would we expect this to do?

>>> with open('test6.txt', mode='w+', encoding='utf-8') as frog_file:
...     new_file.write("I am a frog\n")
...     new_file.write("You are a frog\n")
...     contents = new_file.read()
...     print(contents)

It prints nothing. If we re-open and read the file, we can see that those things were, indeed, written to the file, so what’s going on here?

Note

I’m going to open the file without with so the file doesn’t close in between the steps we take.

>>> frog_file = open('test7.txt', mode='r+')
>>> contents = frog_file.read()
>>> print(contents)
I am a frog.
You are a frog.

Let’s try to write more to the file:

>>> frog_file.write("We are frogs.\n")
13
>>> contents = frog_file.read()
>>> print(contents)

>>>

It prints nothing again, even though when we wrote to the file, Python returned the number of characters we wrote, so we know something’s being written.

The problem is where we’re reading from. This is where seek, Python’s way of moving around a file will come in handy.

>>> frog_file.seek(0)
0
>>> contents = frog_file.read()
>>> print(contents)
I am a frog.
You are a frog.
We are frogs.

>>>

seek(0) moves us to the beginning of the file, and read() reads the file from that point on. Python automatically moves the “cursor” to the end of the last action you took, and every following action starts at that point. What happens if we write now?

>>> frog_file.write("Of course we aren't frogs.\n")
27

We wrote 27 characters. But where are we in the file? We can use tell() to find out:

>>> frog_file.tell()
69

For those of us not keeping track, 69 is the end of the file. Reading the file at this point will do nothing.

>>> contents = frog_file.read()
>>> print(contents)

But if we move to the beginning of the file, we can read and print the entire file.

>>> frog_file.seek(0)
0
>>> contents = frog_file.read()
>>> print(contents)
I am a frog.
You are a frog.
We are frogs.
Of course we aren't frogs.

One more bit about position and seeking. Let’s move to the beginning of the file and write.

>>> frog_file.seek(0)
0
>>> frog_file.write("I am not a frog.\n")
16
>>> frog_file.seek(0)
0
>>> contents = frog_file.read()
>>> print(contents)
I am not a frog.
 are a frog.
We are frogs
Of course we aren't frogs.

What we wrote over-wrote the beginning of the file. The moral of the story? Always check where you are in the file. :)