简体   繁体   中英

file not write in current file position

with open('test.txt', 'w+') as f:
    f.write('foo')
    f.seek(0)
    f.read(1)
    print f.tell() # 1
    f.write('bar')

I want the result to be fbar but it returns foobar . Obviously, file does not write at the current file position.

with open('test.txt', 'w+') as f:
    f.write('foo')
    f.seek(0)
    f.read(1)
    m = f.tell() # 1
    f.seek(m)
    f.write('bar')

It works as I expect.

why do I need seek again while the current file position is already in 1 ?

this is caused by the fact that open returns a buffered file object.

When you're reading, it reads all the file behind the scenes because of buffering (because reading char by char from disk is inefficient).

f.tell() is coherent with what you've read, but internally when you write, the file pointer is somewhere else, that's why you have to workaround it by forcing the seek .

That's only the "why?", but IMHO it's a bug (or a limitation), as write should/could use user-known position not internal system position of the underlying unbuffered file.

That's not a problem on read-only or write-only streams, but that's a problem in that interesting case.

So now you know: to read after a write or write after a read , always use seek even if you think that the position of the file is correct.

As an alternative, you could use os.open to make sure buffering isn't involved (with some adaptations for the system calls as ftell doesn't exist, you have to seek 0 from current to get current pos):

import os

f = os.open('test.txt',os.O_RDWR|os.O_TRUNC)
os.write(f,b'foo')   # b prefix needed, stream is binary
os.lseek(f, 0, os.SEEK_SET)
os.read(f,1)
# print(os.lseek(f, 0, os.SEEK_CUR)) # to seek/get current
os.write(f,b'bar')
os.close(f)

you get fbar all right in that case (even when disabling the lseek statement)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM