Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]


Groups > comp.lang.python > #68304

Re: Save to a file, but avoid overwriting an existing file

Date 2014-03-13 09:19 +1100
From Cameron Simpson <cs@zip.com.au>
Subject Re: Save to a file, but avoid overwriting an existing file
References <lfpjv9$tki$1@news1.carnet.hr>
Newsgroups comp.lang.python
Message-ID <mailman.8109.1394664190.18130.python-list@python.org> (permalink)

Show all headers | View raw


On 12Mar2014 13:29, zoom <zoom@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@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.

Back to comp.lang.python | Previous | NextPrevious in thread | Next in thread | Find similar | Unroll thread


Thread

Save to a file, but avoid overwriting an existing file zoom <zoom@yahoo.com> - 2014-03-12 13:29 +0100
  Re: Save to a file, but avoid overwriting an existing file Skip Montanaro <skip@pobox.com> - 2014-03-12 07:37 -0500
  Re: Save to a file, but avoid overwriting an existing file Tim Chase <python.list@tim.thechases.com> - 2014-03-12 08:33 -0500
  Re:Save to a file, but avoid overwriting an existing file Dave Angel <davea@davea.name> - 2014-03-12 14:22 -0400
  Re: Save to a file, but avoid overwriting an existing file Emile van Sebille <emile@fenx.com> - 2014-03-12 12:38 -0700
  Re: Save to a file, but avoid overwriting an existing file Cameron Simpson <cs@zip.com.au> - 2014-03-13 09:19 +1100
  Re: Save to a file, but avoid overwriting an existing file Mark Lawrence <breamoreboy@yahoo.co.uk> - 2014-03-12 23:04 +0000
  Re: Save to a file, but avoid overwriting an existing file Ben Finney <ben+python@benfinney.id.au> - 2014-03-13 11:22 +1100

csiph-web