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