Author josh.r
Recipients ajaksu2, atila-cheops, brian.curtin, cgohlke, cheops, effbot, josh.r, rcronk, tim.golden, tim.peters
Date 2014-07-04.02:38:54
SpamBayes Score -1.0
Marked as misclassified Yes
Message-id <1404441535.9.0.612567396217.issue1425127@psf.upfronthosting.co.za>
In-reply-to
Content
Similar reference regarding the same basic behavior: http://blogs.msdn.com/b/oldnewthing/archive/2012/09/07/10347136.aspx

Short version: Indexing and anti-virus tools prevent deletion from occurring.

Longer version: 
DeleteFile (and all the stuff that ultimately devolves to DeleteFile) operate in a funny way on Windows. Internally, it opens a HANDLE to the file, marks it as pending deletion, and closes the HANDLE. If no one snuck in and grabbed another HANDLE to the file during that time, then the file is deleted when DeleteFile's hidden HANDLE is closed. Well designed anti-virus/indexing tools use oplocks ( http://blogs.msdn.com/b/oldnewthing/archive/2013/04/15/10410965.aspx ) so they can open a file, but seamlessly get out of the way if a normal process needs to take exclusive control of a file or delete it. Sadly "well-designed" is not a term usually associated with anti-virus tools, so errors like this are relatively commonplace.

Workarounds like using GetTempFileName() and MoveFile() to move the file out of the way will work, though I believe they introduce their own race conditions (the temp file itself is created but the HANDLE is closed immediately, which could mean a race to open the empty file by the bad anti-virus that would block MoveFile()).

Basically, if you're running on Windows, and you're using unfriendly anti-virus/indexing tools, there is no clean workaround that maintains the same behavior. You can't keep creating and deleting a file of the same name over and over without risking access denied errors.

That said, you could probably get the same results by opening and closing the file only once. Change from the original pseudocode:

while 1:
    with open(myfilename, ...) as myfile:
        myfile.write(...)
    do_stuff_with(myfilename)
    os.remove(myfilename)

to (assuming the default file sharing permissions are amenable):

with open(myfilename, ...) as myfile:
    while 1:
        myfile.write(...)
        myfile.flush()
        myfile.seek(0)
        do_stuff_with(myfilename)
        myfile.truncate()

Same basic pattern, except this time, you're rebuilding the same file over and over without ever leaving it unowned long enough for anti-virus/indexing to swoop in and steal it from you.
History
Date User Action Args
2014-07-04 02:38:56josh.rsetrecipients: + josh.r, tim.peters, effbot, atila-cheops, ajaksu2, tim.golden, brian.curtin, cheops, rcronk, cgohlke
2014-07-04 02:38:55josh.rsetmessageid: <1404441535.9.0.612567396217.issue1425127@psf.upfronthosting.co.za>
2014-07-04 02:38:55josh.rlinkissue1425127 messages
2014-07-04 02:38:54josh.rcreate