Assume there is a file test.txt containing a string 'test'.
Now, consider the following Python code:
f = open('test', 'r+')
f.read()
f.truncate(0)
f.write('passed')
f.flush();
Now I expect test.txt to contain 'passed' now, however there are additionally some strange symbols!
Update: flush after truncate does not help.
This is because truncate doesn’t change the stream position.
When you
read()the file, you move the position to the end. So successivewrites will write to file from that position.However, when you callflush(), it seems not only it tries to write the buffer to the file, but also does some error checking and fixes the current file position. WhenFlush()is called after thetruncate(0), writes nothing (buffer is empty), then checks the file size and places the position at the first applicable place (which is0).UPDATE
Python’s file function are NOT just wrappers around the C standard library equivalents, but knowing the C functions helps knowing what is happening more precisely.
From the ftruncate man page:
From the fflush man page:
This means if you put
flushbeforetruncateit has no effect. I checked and it was so.But for putting
flushaftertruncate:The man page doesn’t mention the seek pointer when explaining output streams with last operation not being input. (Here our last operation is
truncate)UPDATE 2
I found something in python source code:
Python-3.2.2\Modules\_io\fileio.c:837Look at the two lines I indicated (
///// This Line /////). If your platform is Windows, then it’s saving the position and returning it back after the truncate.To my surprise, most of the
flushfunctions inside the Python 3.2.2 functions either did nothing or did not callfflushC function at all. The 3.2.2 truncate part was also very undocumented. However, I did find something interesting in Python 2.7.2 sources. First, I found this inPython-2.7.2\Objects\fileobject.c:812intruncateimplementation:So to summarize all, I think this is a fully platform dependent thing. I checked on default Python 3.2.2 for Windows x64 and got the same results as you. Don’t know what happens on *nixes.