Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I create an incrementing filename in Python?

Tags:

python

file-io

I'm creating a program that will create a file and save it to the directory with the filename sample.xml. Once the file is saved when i try to run the program again it overwrites the old file into the new one because they do have the same file name. How do I increment the file names so that whenever I try to run the code again it will going to increment the file name. and will not overwrite the existing one. I am thinking of checking the filename first on the directory and if they are the same the code will generate a new filename:

fh = open("sample.xml", "w") rs = [blockresult] fh.writelines(rs) fh.close() 
like image 987
Oliver Ven Quilnet Avatar asked Aug 01 '13 03:08

Oliver Ven Quilnet


People also ask

How do you create a folder in Python?

To create a new directory, you use os. mkdir() function. And you should always check if a directory exists first before creating a new directory. The following example creates a new directory called python under the c:\temp directory.


2 Answers

I would iterate through sample[int].xml for example and grab the next available name that is not used by a file or directory.

import os  i = 0 while os.path.exists("sample%s.xml" % i):     i += 1  fh = open("sample%s.xml" % i, "w") .... 

That should give you sample0.xml initially, then sample1.xml, etc.

Note that the relative file notation by default relates to the file directory/folder you run the code from. Use absolute paths if necessary. Use os.getcwd() to read your current dir and os.chdir(path_to_dir) to set a new current dir.

like image 142
bossi Avatar answered Nov 05 '22 07:11

bossi


Sequentially checking each file name to find the next available one works fine with small numbers of files, but quickly becomes slower as the number of files increases.

Here is a version that finds the next available file name in log(n) time:

import os  def next_path(path_pattern):     """     Finds the next free path in an sequentially named list of files      e.g. path_pattern = 'file-%s.txt':      file-1.txt     file-2.txt     file-3.txt      Runs in log(n) time where n is the number of existing files in sequence     """     i = 1      # First do an exponential search     while os.path.exists(path_pattern % i):         i = i * 2      # Result lies somewhere in the interval (i/2..i]     # We call this interval (a..b] and narrow it down until a + 1 = b     a, b = (i // 2, i)     while a + 1 < b:         c = (a + b) // 2 # interval midpoint         a, b = (c, b) if os.path.exists(path_pattern % c) else (a, c)      return path_pattern % b 

To measure the speed improvement I wrote a small test function that creates 10,000 files:

for i in range(1,10000):     with open(next_path('file-%s.foo'), 'w'):         pass 

And implemented the naive approach:

def next_path_naive(path_pattern):     """     Naive (slow) version of next_path     """     i = 1     while os.path.exists(path_pattern % i):         i += 1     return path_pattern % i 

And here are the results:

Fast version:

real    0m2.132s user    0m0.773s sys 0m1.312s 

Naive version:

real    2m36.480s user    1m12.671s sys 1m22.425s 

Finally, note that either approach is susceptible to race conditions if multiple actors are trying to create files in the sequence at the same time.

like image 33
James Avatar answered Nov 05 '22 08:11

James