homepage

This issue tracker has been migrated to GitHub , and is currently read-only.
For more information, see the GitHub FAQs in the Python's Developer Guide.

Author vstinner
Recipients eric.araujo, eric.smith, exarkun, giampaolo.rodola, meatballhat, olemis, pitrou, tarek, vstinner
Date 2010年05月26日.23:18:50
SpamBayes Score 0.03151871
Marked as misclassified No
Message-id <1274915932.43.0.889518350451.issue8604@psf.upfronthosting.co.za>
In-reply-to
Content
> This sounds silly to me. You can write a file in two lines:
>
> with open("foo", "wb") as f:
> f.write(contents)
If the disk is full, write fails and the new file only contains a part of 'contents'. If the file does already exist and the write fails, the original content is lost.
The correct pattern is something like:
@contextlib.contextmanager
def atomic_write(filename):
 tempname = filename + ".tmp"
 out = open(tempname, "w")
 try:
 yield out
 if hasattr('os', 'fsync'):
 os.fsync(out.fileno())
 out.close()
 if os.name in ('nt', 'ce'):
 os.unlink(filename)
 # ... hope that it doesn't fail here ...
 os.rename(tempname, filename)
 except:
 out.close()
 os.unlink(tempname)
 raise
Remarks:
 - call fsync() to ensure that the new file content is written on disk. it does nothing on Mac OS X
 - on Windows, it's not possible to rename a to b if b does already exist. New Windows versions has an atomic function: MoveFileTransacted(). Older versions have MoveFileEx(MOVEFILE_REPLACE_EXISTING | MOVEFILE_WRITE_THROUGH) and ReplaceFile()
This context manager is *not* atomic on any OS. It's only atomic on some OS, and it may depends on the kernel version (see recent discussions about ext3/ext4, fsync and write barrier).
History
Date User Action Args
2010年05月26日 23:18:52vstinnersetrecipients: + vstinner, exarkun, pitrou, eric.smith, giampaolo.rodola, tarek, eric.araujo, olemis, meatballhat
2010年05月26日 23:18:52vstinnersetmessageid: <1274915932.43.0.889518350451.issue8604@psf.upfronthosting.co.za>
2010年05月26日 23:18:50vstinnerlinkissue8604 messages
2010年05月26日 23:18:50vstinnercreate

AltStyle によって変換されたページ (->オリジナル) /