How come a file doesn't get written until I stop the program?

Question:

I’m running a test, and found that the file doesn’t actually get written until I control-C to abort the program. Can anyone explain why that would happen?

I expected it to write at the same time, so I could read the file in the middle of the process.

import os
from time import sleep

f = open("log.txt", "a+")
i = 0
while True:
  f.write(str(i))
  f.write("n")
  i += 1
  sleep(0.1)
Asked By: Marvin K

||

Answers:

You need to f.close() to flush the file write buffer out to the file. Or in your case you might just want to do a f.flush(); os.fsync(); so you can keep looping with the opened file handle.

Don’t forget to import os.

Answered By: deed02392

You will want to check out file.flush() – although take note that this might not write the data to disk, to quote:

Note:
flush() does not necessarily write the file’s data to disk. Use flush() followed by os.fsync() to ensure this behavior.

Closing the file (file.close()) will also ensure that the data is written – using with will do this implicitly, and is generally a better choice for more readability and clarity – not to mention solving other potential problems.

Answered By: Gareth Latty

This is a windows-ism. If you add an explicit .close() when you’re done with file, it’ll appear in explorer at that time. Even just flushing it might be enough (I don’t have a windows box handy to test). But basically f.write does not actually write, it just appends to the write buffer – until the buffer gets flushed you won’t see it.

On unix the files will typically show up as a 0-byte file in this situation.

Answered By: Tyler Eaves

Writing to disk is slow, so many programs store up writes into large chunks which they write all-at-once. This is called buffering, and Python does it automatically when you open a file.

When you write to the file, you’re actually writing to a “buffer” in memory. When it fills up, Python will automatically write it to disk. You can tell it “write everything in the buffer to disk now” with

f.flush()

This isn’t quite the whole story, because the operating system will probably buffer writes as well. You can tell it to write the buffer of the file with

os.fsync(f.fileno())

Finally, you can tell Python not to buffer a particular file with open(f, "w", 0) or only to keep a 1-line buffer with open(f,"w", 1). Naturally, this will slow down all operations on that file, because writes are slow.

Answered By: Katriel

File Handler to be flushed.

f.flush()

The file does not get written, as the output buffer is not getting flushed until the garbage collection takes effect, and flushes the I/O buffer (more than likely by calling f.close()).

Alternately, in your loop, you can call f.flush() followed by os.fsync(), as documented here.

f.flush()
os.fsync()

All that being said, if you ever plan on sharing the data in that file with other portions of your code, I would highly recommend using a StringIO object.

Answered By: nesv

You have to force the write, so I i use the following lines to make sure a file is written:

# Two commands together force the OS to store the file buffer to disc
    f.flush()
    os.fsync(f.fileno())
Answered By: Gil.I
Categories: questions Tags: , ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.