I've come across this strange behavior regarding opening a file in append mode and then attempting to seek to the start of the file.
The code should be self-explanatory: In the second open, I expect to be able to write a string to the beginning of the file and then have f.tell()
return 5 (the number of bytes written at the beginning of the file).
The thing is that in Python 2.6.6 and 2.7.6 the final assert fires but, surprisingly, it works in Python 3.3.2.
# Create new file, write after the 100th byte.
f = open("test", "w+b")
f.seek(100, 0)
f.write(b"end")
assert f.tell() == 100 + len("end")
f.close()
# Open file for writing without overwriting, attempt to write at start of file
# of the file, but doesn't.
f = open("test", "a+b")
f.seek(0, 0)
f.write(b"start")
assert f.tell() == len("start")
f.close()
So I made a C program that does the equivalent. It actually behaves like the Python 2.x versions:
#include <stdio.h>
int main() {
FILE *f = fopen("tt", "w+b");
fseek(f, 100, 0);
fwrite("x", 1, 1, f);
fclose(f);
f = fopen("tt", "a+b");
fseek(f, 0, 0);
fwrite("y", 1, 1, f);
printf("%ld\n", ftell(f));
fclose(f);
return 0;
}
This prints 102
, and I consider this canonical (I've looked at strace -eopen,close,lseek
outputs as well, but am none the smarter).
So my question is: What kind of embarrassingly basic knowledge do I not have?
And why does Python 3 behave differently?
By the way, I'm on Linux.