Re[2]: [Tutor] fileobject.close() question

MICHAEL.W.WILSON@CUSTOMS.TREAS.GOV MICHAEL.W.WILSON@CUSTOMS.TREAS.GOV
Thu, 13 Apr 2000 08:48:27 -0400


     If the file object is closed at gc (in this case, at the end of the 
     program) and before the buffer is gc'd, why doesn't that close flush 
     the buffer out to the file?  I was under the impression that the 
     buffer was gc'd first and then the close was called (therefore 
     explaining why bytes are lost), the other way doesn't seem to explain 
     what happens.
     
     Mike


______________________________ Reply Separator _________________________________
Subject: Re: [Tutor] fileobject.close() question 
Author:  Corran Webster <cwebster@nevada.edu> at smtplink
Date:    4/12/00 4:23 PM


> This has to do with buffer flushing, to be honest I'm not sure how to set 
> autoflushing with python (perl would be $| = 1;),
     
file = open("filename", "w", 0)
     
The third (and optional) parameter is the buffer size; 0 means unbuffered.
     
You can also flush the file explicitly at any time with
     
file.flush()
     
> but anyway, the buffer
> waits to be filled before it writes and it flushes on a close.  If you
> don't write enough to fill the buffer, and the program exits, the buffer is 
> cleaned up before the close occurs, therefore the remaining bytes are lost. 
> Not closing a file handle is not a big deal with reads (at all), but I'd
> be careful with writes.
     
This is partially correct - while the original problem was caused in part 
by the  buffer not having been written to the disk yet, Python file objects 
automatically call their close() methods when they are garbage collected 
(ie. at a random time, but surely before Python shuts itself down).
     
So you do not need to worry about buffers not being flushed unless Python 
crashes (and if this is a problem, even an explicit close() may not help 
you if Python never reaches it).  For long-running programs you will always 
want to explicitly close() files, particularly if there could be circular 
references floating around which will prevent timely garbage collection of 
your file.
     
On to the original question:
     
> Subject: [Tutor] fileobject.close() question
> Author:  Tim Condit <timc@ans.net> at smtplink 
> Date:    4/12/00 6:38 PM
>
>
>
> Greetings,
>
> I'm wondering about something Pythonic. The first time I ran the little
> code snip below, I left the 'fileobject.close()' function out. Basically, 
> I forgot it, but at the same time, in the Quick Python book, pg. 132,
> section 13.2, curiously enough, it says: 
>
>         "In small scripts, not closing a file object will generally 
>         not have much of an effect.."
     
Notice the "scripts" above.
     
> I'm seeing something different. Before I caught my oversight, I ran this
> same little snip twice.. the first time to create the file, and the second 
> time to trigger the else: statement. The file was created, but nothing was 
> written to it, until I went back and added fileobject.close(). Does anyone 
> know what is causing this to happen?
>
>
> Thanks,
> Tim
>
> FYI: the third line (testfile = ...) is all on one line) 
>
>
> >>> dir()
> ['__builtins__', '__doc__', '__name__'] 
> >>> import os
> >>> testfile = os.path.join('/', 'afs', 'ans.net', 'user', 'timc', 
> 'testfile')
> >>> if not os.path.isfile(testfile):
> ..     fileobject = open(testfile, 'w') 
> ..     fileobject.write("hi there.")
> ..     fileobject.close()
> .. else:
> ..     print "Sorry, that file already exists." 
> ..
> >>>
     
It looks like you're running this from the interactive prompt.  If this is 
the case, I suspect that what happened was:
     
  - You ran it the first time from the interactive prompt.  This opened the
    file, but because the data was smaller than the buffer, it wasn't flushed 
    and so nothing had yet been written to disk.  Also, since you did not 
    explicitly close(), your file is still open, and fileobject references it, 
    so it will not be garbage collected.
     
  - you ran it a second time from the command line (without exiting the
    interpreter, so fileobject still exists).  Because the data still had 
    not been written, the file doesn't exist yet on the disk, and it doesn't 
    work as you expect.
     
  - when you add the close(), it explicitly closes the file, which flushes the
    data and creates the file in the filesystem; and so the second time you 
    run it, all is well.
     
However, if you had put exactly the original code:
     
import os
testfile = os.path.join('/', 'afs', 'ans.net', 'user', 'timc', 'testfile') 
if not os.path.isfile(testfile):
    fileobject = open(testfile, 'w')
    fileobject.write("hi there.")
else:
    print "Sorry, that file already exists."
     
     
into it's own little script and run it twice via:
     
python myfile.py
     
it would have worked perfectly without the explicit close.  This is the 
behaviour that the comment in Quick Python is referring to.
     
     
Regards,
Corran
     
     
     
_______________________________________________ 
Tutor maillist  -  Tutor@python.org
http://www.python.org/mailman/listinfo/tutor