Save to a file, but avoid overwriting an existing file

Mark Lawrence breamoreboy at yahoo.co.uk
Wed Mar 12 19:04:13 EDT 2014


On 12/03/2014 22:19, Cameron Simpson wrote:
> 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,
>

I haven't looked but would things be easier if the new exception 
hierarchy were used 
http://docs.python.org/3.3/whatsnew/3.3.html#pep-3151-reworking-the-os-and-io-exception-hierarchy 
?

-- 
My fellow Pythonistas, ask not what our language can do for you, ask 
what you can do for our language.

Mark Lawrence

---
This email is free from viruses and malware because avast! Antivirus protection is active.
http://www.avast.com





More information about the Python-list mailing list