2

I'm in the Python shell and I'm trying to understand the basics. Here is what I have typed:

doc = open('test.txt', 'w') # this opens the file or creates it if it doesn't exist
doc.write('blah blah')
doc.truncate()

I understand the first line. However, in the second line, isn't it supposed to write 'blah blah' to the file? It doesn't do that. However, when I run a truncate function to the file, 'blah blah' suddenly shows up. Can someone explain to me how this logic works?

I thought truncate was supposed to erase the contents of the file? Why does it make the previous write line show up?

Russia Must Remove Putin
  • 374,368
  • 89
  • 403
  • 331
J82
  • 8,267
  • 23
  • 58
  • 87
  • You can see answer here: http://stackoverflow.com/questions/26917197/what-exactly-does-truncate-do-in-this-case – merenptah Nov 13 '14 at 20:13
  • @merenptah That was my previous question. I understand what `truncate` does but it doesn't work as expected in this case which is why I opened up a second, more specific question. – J82 Nov 13 '14 at 20:14
  • 2
    the write will be cached, and may not show up until you either flush the buffer or close the file, and truncate may well flush the buffer before setting the file size. – Tony Suffolk 66 Nov 13 '14 at 20:19
  • @Tony When the second line is written, the file is already closed. When I open it up after the second line to check if `blah blah` was written in it, I see nothing. Then I close the file again and type in the third line. After typing the third line, I open the file again and I see that `blah blah` has been written. Every time I close the file, doesn't that mean that the buffer is flushed meaning that `blah blah` should have been written in the file after the second line? – J82 Nov 13 '14 at 20:24
  • so your code snippet isn't complete - as your code says nothing about closing the files. – Tony Suffolk 66 Nov 13 '14 at 20:31
  • @Tony Ok, I think there is a misunderstanding on my part here. When I say 'open` or 'close' the file, I'm talking about closing the text file, like clicking the X in the corner of notepad. Obviously, this is wrong. I guess I have to add `doc.close()` after the second and third lines? – J82 Nov 13 '14 at 20:35
  • no - if you want the text to be output immediately - use `doc.flush()`, this flushes the buffer to disk. Closing the file in Notepad wont close the file in python, or flush the python buffer. – Tony Suffolk 66 Nov 13 '14 at 20:42
  • J82, if you'll use the context manager, you don't need to do `doc.close()`. It's a known best practice, and it's in the documentation. For some reason they stick it right at the end of the section, all the while calling it a best practice: https://docs.python.org/2/tutorial/inputoutput.html#methods-of-file-objects "It is good practice to use the with keyword when dealing with file objects. This has the advantage that the file is properly closed after its suite finishes, even if an exception is raised on the way. It is also much shorter than writing equivalent try-finally blocks:" – Russia Must Remove Putin Nov 13 '14 at 20:43
  • @Tony When I use `doc.flush()`, I see that `blah blah` shows up in the text file, but there is a huge leading blank space before the words. What is the cause of this? – J82 Nov 13 '14 at 20:55

3 Answers3

3

From the manual:

file.truncate([size])

[...] The size defaults to the current position [...]

so as you have opened and written to the file, the current position is the end of the file. Basically, you are truncating from the end of the file. Hence the absence of effect other than actually flushing the buffers, and getting the text written to disk. (truncate flushes before truncating)

Try with truncate(0); that will empty the file.

damienfrancois
  • 52,978
  • 9
  • 96
  • 110
  • But I'm trying to write `blah blah` to the file after the second line. Isn't that what `write` is supposed to do or do I have that part confused? Why does `blah blah` show up after the third line? – J82 Nov 13 '14 at 20:26
  • `write` is a buffered write. It gets written to the disk whenever the operating systems feels it. Use `flush` to push the buffers to the disk. – damienfrancois Nov 13 '14 at 20:31
1

Same as you with the context manager instead:

with open('test.txt', 'w') as doc:
    doc.write('blah blah')
    # doc.truncate() 

The above will truncate to the current position, which is at the end of the file, meaning it doesn't truncate anything.

Do this instead, it will truncate the file at the 0th byte, effectively clearing it.

    doc.truncate(0) 

I see from your comments that you may still be having trouble, trouble that may be solved by using the context manager:

>>> def foofile():
...     with open('/temp/foodeleteme', 'w') as foo:
...         foo.write('blah blah blah')
...         foo.truncate(0)
...     with open('/temp/foodeleteme') as foo:
...         print foo.read()
...         
>>> foofile()

prints nothing.

Russia Must Remove Putin
  • 374,368
  • 89
  • 403
  • 331
0

If you don't specify size parameter. The function take current position.

If you want to erase content of file:

doc = open('test.txt', 'w') # this opens the file or creates it if it doesn't exist
doc.write('blah blah')
doc.truncate(0)

or better:

with open('test.txt', 'w') as doc:
    doc.write('blah blah')
    doc.truncate(0)
Patrick Mevzek
  • 10,995
  • 16
  • 38
  • 54
merenptah
  • 476
  • 4
  • 15