4

How can I generate a unique filename or path? I am looking for a solution that works both for Unix(-like) operating systems as well as Windows.

stakx - no longer contributing
  • 83,039
  • 20
  • 168
  • 268
pandreym
  • 137
  • 1
  • 3
  • 11

6 Answers6

6

Use boost::uuid:

#include <string>
using std::string;

#include <boost/lexical_cast.hpp>
using boost::lexical_cast;

#include <boost/uuid/uuid.hpp>
using boost::uuids::uuid;

#include <boost/uuid/uuid_generators.hpp>
using boost::uuids::random_generator;

#include <boost/uuid/uuid_io.hpp>

string make_uuid()
{
    return lexical_cast<string>((random_generator())());
}

And use the generated UUID as the filename (the path is therefore irrelevant).

hmjd
  • 120,187
  • 20
  • 207
  • 252
  • 2
    but would this *guarantee* a unique filename and deal with race conditions? – Component 10 Aug 16 '12 at 09:18
  • @Component10, from the documentation linked: _When UUIDs are generated by one of the defined mechanisms, they are either guaranteed to be unique, different from all other generated UUIDs (that is, it has never been generated before and it will never be generated again), or it is extremely likely to be unique (depending on the mechanism)._ So the definitive answer to your question would be it is not 100% guaranteed. However, I have used this for quite sometime and _never_ had a clash. – hmjd Aug 16 '12 at 09:22
  • Agreed, I am being pedantic given the range of the uuid. :) The main issue that I see here is how to ensure that your file does not already exist when you open it. A discussion on this problem can be found here [http://stackoverflow.com/questions/9874002/how-to-create-a-file-only-if-it-doesnt-exist] though clearly the more unique you make the name of the file, as in your answer, the less likely this is to happen. – Component 10 Aug 16 '12 at 09:47
  • 1
    @Component10: in practice, you really don't need to worry about GUID collisions. See http://thedailywtf.com/Articles/GUGUID.aspx – Harry Johnston Aug 16 '12 at 22:10
5

Use mktemp on both. Windows have got a version of the posix call at msdn docs and the linux call is mktemp(3). mktemp command lines tool on linux incidentally just calls that

MSalters
  • 173,980
  • 10
  • 155
  • 350
Osada Lakmal
  • 891
  • 2
  • 8
  • 22
2

As mentionned elsewhere, there is tmpnam. It's often poorly implemented, so as to allow race conditions with other processes. On a typical single user machine, however, it's often sufficient.

In my own code, I'll generally create a directory, with the process id as part of the name, and arrange to put all of my temporary files in it (using a simple counter to vary the file names); on a shared disk, I'd also mangle the processor id into the directory name (but I tend to put temporary files on a local, non-shared drive, which avoids most of the problems).

James Kanze
  • 150,581
  • 18
  • 184
  • 329
  • 1
    @user1602627 What do you mean by "more unique"? The name is either unique, or it isn't. You can generate any name you want, mangling in all sorts of various information, like process id, user id, time (in microseconds, if you want), machine MAP address, etc., etc. Throw in some bytes you've read from `/dev/random` as well, if you want. – James Kanze Aug 16 '12 at 10:11
  • the process id thing is good, thank you! i will use it – Alexander Ivanov Sep 30 '21 at 17:54
0
  • Easiest way: Generate a random number and use its hex value as the file name (unless the file exists, in which case you create a new one).

  • Easiest way 2: If you just need some file not existing, use a number (or its hex value) as the file name or a part of it, where you just increase the number till no file with that name exists already.

  • More complex way: Generate a GUID and use it as the file name (again verify it's not in use).

Mario
  • 35,726
  • 5
  • 62
  • 78
0

You can get current timestamp and use it as a filename. Or just increase last filename by 1.
As example 1.txt, 2.txt and so on.

LLAlive
  • 427
  • 5
  • 24
0

Use the C-library function tmpfile or tmpnam. Both exist under windows and linux.

But beware, when using tmpfile, it got automatic deleted when you close your program, so maybe tmpnam is more suited for you.

flolo
  • 15,148
  • 4
  • 32
  • 57
  • 2
    From the Linux manual page for tmpnam: "Never use this function. Use mkstemp(3) or tmpfile(3) instead." – Thomas Padron-McCarthy Aug 16 '12 at 08:36
  • @ThomasPadron-McCarthy: You are right, that there are possible security problems, when someone "hijacks" your file between getting the name and opening the file. Usually if it is tempory tmpfile is the way to got. But in this case, the user maybe want to make it persisitent. And with mkstemp I wasnt sure, if its available under windows. – flolo Aug 16 '12 at 08:43
  • Which is a problem with Linux, not `tmpnam`. There's no reason not to use `tmpnam` if it's implemented correctly. (To be fair, it rarely is implemented in a safe manner. But `mkstemp` is Unix, not standard C, and `tmpfile` not only creates a name, but opens the file as a `FILE*`, which makes it pretty useless.) – James Kanze Aug 16 '12 at 08:43
  • 1
    @flolo The security issue is rather far-fetched. It's possible, but not very likely; for a typical single user desktop machine, `tmpnam` is probably sufficient. (In order to hijack the name, the virus has to know that it is being generated, and run in the very, very small time slot between the generation and the creation of the file. Not to mention that under Unix, at least, and probably under Windows as well, you can request that the `open` fail if the file already exists.) – James Kanze Aug 16 '12 at 08:54