pythonpython-3.xfilemethods

Why is the following behaviour observed while dealing with a text file object opened with 'r+' mode in Python?


I was going through file handling in Python and experimenting with different file modes. In a certain scenario with file mode as 'r+', I was unable to make sense of what was happening while using the read and write methods one after the other (with respect to the file pointer's position).

The contents of my test file (with nothing more than just plain ascii characters) and my interaction with the Python interpreter containing the said scenario are given below:

aTestTextFile3.txt:

012345678901234567890123456789

Python interpreter:

>>> f = open('aTestTextFile3.txt', 'r+')

(File pointer at the beginning)

>>> f.read()
'012345678901234567890123456789'

(File pointer at the end)

>>> f.seek(0); f.write('MONTUEWED')
0
9

(File pointer finally at position 9 (considering the initial position to be 0))

>>> f.seek(0); f.read()
0
'MONTUEWED901234567890123456789'

(File pointer finally at the end)

>>> f.tell()
30

(Current file pointer position confirmed)

>>> f.seek(0); f.read(9)
0
'MONTUEWED'

(File pointer finally at position 9 (considering the initial position to be 0))

>>> f.tell()
9

(Current file pointer position confirmed)

>>> f.write('THURS')
5
>>> f.tell()
35

(Turned out that 'THURS' was written at the end of the file)

>>> f.seek(0); f.read()
0
'MONTUEWED901234567890123456789THURS'

(The previous point confirmed)

Despite a tell method call stating that the file pointer's position was 9 before writing 'THURS', 'THURS' was written at the end. Why is it so? Was it because of the read method call preceding it?

(Interaction continued...)

>>> f.seek(0); f.read(9)
0
'MONTUEWED'

(File pointer finally at 9)

>>> f.tell()
9

(Current file pointer position confirmed)

>>> f.seek(0, 1)
9

(File pointer moved to the current position with no offset, which is still 9, right?)

>>> f.write('THURS')
5

(Originally, I would think of 'THURS' being written after 'WED', but in the previous scenario, 'THURS' was written at the end; What would happen now?)

>>> f.tell()
14

('THURS' was written after 'WED', unlike in the previous scenario)

>>> f.seek(0); f.read()
0
'MONTUEWEDTHURS4567890123456789THURS'

(The previous point confirmed)

Should the file pointer always be moved to its current position using the seek method before making a write method call provided there is at least one read method call preceding the write method call? (I think this question will be answered if the previous question is answered)

(Interaction continued...)

>>> f.seek(0); f.write('Greetings to thee!')
0
18

(File pointer finally at position 18)

>>> f.read()
'890123456789THURS'

(The previous point confirmed)

>>> f.seek(0); f.read()
0
'Greetings to thee!890123456789THURS' 

There seems to be no problem using the read method after a write method call.


Solution

  • >>> f.seek(0); f.read(9)
    0
    'MONTUEWED'
    

    (File pointer finally at position 9 (considering the initial position to be 0))

    >>> f.tell()
    9
    

    (Current file pointer position confirmed)

    >>> f.write('THURS')
    5
    >>> f.tell()
    35
    

    (Turned out that 'THURS' was written at the end of the file)

    Apparently the Python implementation tacitly imposes a similar restriction for intermixed reads and writes as ANSI C that a file positioning function intervene between input and output, and the above violated this.

    Should the file pointer always be moved to its current position using the seek method before making a write method call provided there is at least one read method call preceding the write method call?

    Yes, it seems, although I don't see it documented.