Save to a file, but avoid overwriting an existing file
Cameron Simpson
cs at zip.com.au
Wed Mar 12 18:19:25 EDT 2014
On 12Mar2014 13:29, zoom <zoom at yahoo.com> wrote:
> I would like to assure that when writing to a file I do not
> overwrite an existing file, but I'm unsure which is the best way to
> approach to this problem. As I can see, there are at least two
> possibilities:
>
> 1. I could use fd = os.open("x", os.O_WRONLY | os.O_CREAT | os.O_EXCL)
> which will fail - if the file exists. However, I would prefer if the
> program would try to save under different name in this case, instead
> of discarding all the calculation done until now - but I' not too
> well with catching exceptions.
Others have menthions tempfile, though of course you have the same collision
issue when you come to rename the temp file if you are keeping it.
I would run with option 1 for your task.
Just iterate until os.open succeeds.
However, you need to distinuish _why_ an open fails. For example,
if you were trying to make files in a directory to which you do not
have write permission, or just a directory that did not exist,
os.open would fail not matter what name you used, so your loop would
run forever.
Therefore you need to continue _only_ if you get EEXIST. Otherwise abort.
So you'd have some code like this (totally untested):
# at top of script
import errno
# where you make the file
def open_new(primary_name):
try:
fd = os.open(primary_name, os.O_WRONLY | os.O_CREAT | os.O_EXCL)
except OSError as e:
if e.errno != errno.EEXIST:
raise
else:
return primary_name, fd
n = 1
while True:
secondary_name = "%s.%d" % (primary_name, n)
try:
fd = os.open(secondary_name, os.O_WRONLY | os.O_CREAT | os.O_EXCL)
except OSError as e:
if e.errno != errno.EEXIST:
raise
else:
return secondary_name, fd
n += 1
# where you need the file
path, fd = open_new("x")
That gets you a function your can reuse which returns the file's
name and the file descriptor.
Cheers,
--
Cameron Simpson <cs at zip.com.au>
Reason #173 to fear technology:
o o o o o o <o <o>
^|\ ^|^ v|^ v|v |/v |X| \| |
/\ >\ /< >\ /< >\ /< >\
o> o o o o o o o
\ x </ <|> </> <\> <)> |\
/< >\ /< >\ /< >\ >> L
Mr. email does the Macarena.
More information about the Python-list
mailing list