File read-write mode: problem appending after reading

Tim Peters tim.peters at gmail.com
Fri Oct 13 03:57:36 EDT 2006


[Frederic Rentsch]
>    Working with read and write operations on a file I stumbled on a
> complication when writes fail following a read to the end.
>
>  >>> f = file ('T:/z', 'r+b')
>  >>> f.write ('abcdefg')
>  >>> f.tell ()
> 30L
>  >>> f.seek (0)
>  >>> f.read ()
> 'abcdefg'
>  >>> f.flush ()  # Calling or not makes no difference
>  >>> f.write ('abcdefg')

Nothing is defined about what happens at this point, and this is
inherited from C.  In standard C, if you want to read following a
write, or write following a read, on the same stream, you must perform
a file-positioning operation (typically a seek) between them.

> Traceback (most recent call last):
>   File "<pyshell#62>", line 1, in -toplevel-
>     f.write ('abcdefg')
> IOError: (0, 'Error')

That's one possible result.  Since nothing is defined, any other
outcome is also a possible result ;-)

> Flushing doesn't help.

Right, and because flush() is not a file-positioning operation.

> I found two work arounds:
>
>  >>> f.read ()
> 'abcdefg'
>  >>> f.read ()   # Workaround 1: A second read (returning an empty string)
> ''
>  >>> f.write ('abcdefg')
> (No error)

Purely an accident; may or may not "work" the next time you try it, or
on another platform; etc.

>  >>> f.read ()
> 'abcdefg'
>  >>> f.seek (f.tell ())   # Workaround 2: Setting the cursor (to where it is!)

That's a correct approach.  f.seek(0, 1) (seek 0 bytes from the
current position) is a little easier to spell.

>  >>> f.write ('abcdefg')
> (No error)
>
> I found no problem with writing into the file. So it looks like it has
> to do with the cursor which a read puts past the end, unless it is past
> the end, in which case it goes back to the end. Is there a less kludgy
> alternative to "fseek (ftell ())"?

As above, you need to seek when switching from reading to writing, or
from writing to reading.



More information about the Python-list mailing list