Best way to generate random file names in Python

123,369

Solution 1

Python has facilities to generate temporary file names, see http://docs.python.org/library/tempfile.html. For instance:

In [4]: import tempfile

Each call to tempfile.NamedTemporaryFile() results in a different temp file, and its name can be accessed with the .name attribute, e.g.:

In [5]: tf = tempfile.NamedTemporaryFile()
In [6]: tf.name
Out[6]: 'c:\\blabla\\locals~1\\temp\\tmptecp3i'

In [7]: tf = tempfile.NamedTemporaryFile()
In [8]: tf.name
Out[8]: 'c:\\blabla\\locals~1\\temp\\tmpr8vvme'

Once you have the unique filename it can be used like any regular file. Note: By default the file will be deleted when it is closed. However, if the delete parameter is False, the file is not automatically deleted.

Full parameter set:

tempfile.NamedTemporaryFile([mode='w+b'[, bufsize=-1[, suffix=''[, prefix='tmp'[, dir=None[, delete=True]]]]]])

it is also possible to specify the prefix for the temporary file (as one of the various parameters that can be supplied during the file creation):

In [9]: tf = tempfile.NamedTemporaryFile(prefix="zz")
In [10]: tf.name
Out[10]: 'c:\\blabla\\locals~1\\temp\\zzrc3pzk'

Additional examples for working with temporary files can be found here

Solution 2

You could use the UUID module for generating a random string:

import uuid
filename = str(uuid.uuid4())

This is a valid choice, given that an UUID generator is extremely unlikely to produce a duplicate identifier (a file name, in this case):

Only after generating 1 billion UUIDs every second for the next 100 years, the probability of creating just one duplicate would be about 50%. The probability of one duplicate would be about 50% if every person on earth owns 600 million UUIDs.

Solution 3

a common approach is to add a timestamp as a prefix/suffix to the filename to have some temporal relation to the file. If you need more uniqueness you can still add a random string to this.

import datetime
basename = "mylogfile"
suffix = datetime.datetime.now().strftime("%y%m%d_%H%M%S")
filename = "_".join([basename, suffix]) # e.g. 'mylogfile_120508_171442'

Solution 4

The OP requested to create random filenames not random files. Times and UUIDs can collide. If you are working on a single machine (not a shared filesystem) and your process/thread will not stomp on itself, use os.getpid() to get your own PID and use this as an element of a unique filename. Other processes would obviously not get the same PID. If you are multithreaded, get the thread id. If you have other aspects of your code in which a single thread or process could generate multiple different temp files, you might need to use another technique. A rolling index can work (if you aren't keeping them so long or using so many files you would worry about rollover). Keeping a global hash/index to "active" files would suffice in that case.

So sorry for the longwinded explanation, but it does depend on your exact usage.

Solution 5

If you need no the file path, but only the random string having predefined length you can use something like this.

>>> import random
>>> import string

>>> file_name = ''.join(random.choice(string.ascii_lowercase) for i in range(16))
>>> file_name
'ytrvmyhkaxlfaugx'
Share:
123,369
zallarak
Author by

zallarak

Updated on November 09, 2021

Comments

  • zallarak
    zallarak over 2 years

    In Python, what is a good, or the best way to generate some random text to prepend to a file(name) that I'm saving to a server, just to make sure it does not overwrite. Thank you!

  • Li-aung Yip
    Li-aung Yip about 12 years
    In a multi-threaded environment, there's a possible race condition involved in the sequence 1. Test if file exists, 2. create file. If another process interrupts yours between steps 1 and 2, and creates the file, when your code resumes it will overwrite the other process' file.
  • bobobobo
    bobobobo about 11 years
    @Li-aungYip In addition can also use 6-8 random character sequence (in case 2 files are generated in the same second).
  • Li-aung Yip
    Li-aung Yip about 11 years
    @bobobobo: Or you could use the tempfile module, which handles this for you. :)
  • Prof. Falken
    Prof. Falken about 11 years
    this is also very useful when you want a unique filename, but don't want it created just yet.
  • Rockallite
    Rockallite over 8 years
    Or use uuid.uuid4().hex to get an hex string without dashes (-).
  • SmallChess
    SmallChess over 8 years
    Would those files get deleted next time I restart my machine?
  • Luca
    Luca almost 8 years
    The problem with this solution is that it generates not only a file name, but also a file that is already open. If you need a temporary file name for a new, not yet existing file (e.g., to use as output of an os command), this will not do. In that case, you can do something like str(uuid.uuid4()) .
  • Levon
    Levon almost 8 years
    @Luca Thanks for the additional comment, that is useful, and noted for future reference. However, OP clearly stated that he/she wanted to save a file, hence need to open it, so this solution provides for that.
  • Luca
    Luca almost 8 years
    It depends. Perhaps he needs the name to construct an appropriate server call. Not sure. At any rate your reply is certainly the more common case.
  • anajem
    anajem about 7 years
    file = str( random.random() )
  • PhoebeB
    PhoebeB almost 7 years
    To avoid: Unicode-objects must be encoded before hashing I changed to md5(str(localtime()).encode('utf-8')).hexdigest()
  • user1767754
    user1767754 over 6 years
    This is generating random numbers, not a random text.
  • AstraSerg
    AstraSerg over 4 years
    I'd suggest to add microseconds i.e. ...strftime("%y%m%d_%H%M%S%f")
  • Peter O.
    Peter O. about 4 years
    Note that a hash of any kind of data (including a timestamp) does not ensure uniqueness by itself (any more than a randomly chosen byte sequence does).
  • rizerphe
    rizerphe almost 4 years
    While this code may solve the question, including an explanation of how and why this solves the problem would really help to improve the quality of your post, and probably result in more up-votes. Remember that you are answering the question for readers in the future, not just the person asking now. Please edit your answer to add explanations and give an indication of what limitations and assumptions apply.
  • David Golembiowski
    David Golembiowski over 3 years
    Thank you. This answer is a good submission, but it helps to provide a more complete demo.
  • user3376851
    user3376851 about 2 years
    This is also a useful alternative to NamedTemporaryFile() if you are blocked from privaleges on C drive for e.g. a work computer. This was the case for me but the uuid method worked as it's just a random string you can save in the local folder