See inline.
Jeroen Mostert said:
Because it doesn't have to.
Actually, it does, because he is trying to get the same functionality as
GetTempFileName. GetTempFileName will create a unique file in the directory
(up to the limit of 65,535 for the directory it is created in). The call
above doesn't create the file.
I'm not contesting the highly unlikely possibility that a new GUID would
conflict with a filename. The point is, it most definitely can-happen when
a 128 bit value is generated by some method other than the one prescribed
for creating GUIDs.
It's not the case where what is in the directory is constrained by a new
GUID, it's when it is not constrained which is the problem. The OP didn't
state anything about what would be in the directory, so I didn't assume it.
I agree that if all you used for the contents of the directory is a new
GUID, then that would be fine (not perfect, but fine).
And if they did, it still wouldn't matter one bit, unless you think
processes are likely to generate identical GUIDs. They're not. This is
what being unique in space and time is all about. It's not magic, it's
just a lot of bits.
No, processes are not likely to generate identical GUIDs, but they can
definitely produce identical 128-bit values, which a GUID happens to be.
It's the method of creation of the GUID that helps to guarantee the
uniqueness of the value, not just the size of the data.
If you don't follow that method though for creating the 128 bit value,
then the probability of a unique value diminishes. There is nothing
stopping a process from using a 128 bit counter starting at 0 (or some other
unsigned 128 bit value) and incrementing up or down. A collision could
easily happen in that manner.
Again though, if there is a constraint that the names of the files that
are in the directory are limited to what is produced by creating new GUIDs
then it would most definitely be fine to use that.
It makes no difference if one process is generating thousands of files, or
thousands of processes are generating thousands of files. The probability
of a clash is still negligible. And I mean NEGLIGIBLE negligible, not
"pretty unlikely". GUIDs generated on one machine are unique by use of a
value based on a time stamp and a uniquifier. By the time your directory
is full enough to make a GUID clash remotely likely, your file system has
long since given up. It's literally not something you worry about.
Well, as stated above, it is if you don't have that constraint, which is
the point I was trying to make all along. There are many methods for
generating 128-bit values. If everyone doesn't play by the same rules, this
can lead to a conflict.
The difference is this: using a GUID guarantees a unique file name by
virtue of GUIDs being unique. Using GetTempFileName() guarantees a unique
file name by virtue of repeatedly generating a file name and creating a
file by that name until it succeeds (hopefully on the first try). Both
"work" in this respect.
Well, they do, but only if you code it that way. If one just assumes
that a GUID will always produce a unique value when compared to other
methods of comparing 128-bit values, then it's going to fail at some point.
So to counter that, you create the unique file name over and over until it
succeeds. Which is exactly what GetTempFileName does. It's at that point
that I ask "why reinvent the wheel if that is not required". If the need is
to generate more than 65,535 temp file names without cycling prefixes (I am
referring to the Win32 API function, not the .NET static method), then yes,
another method is needed.
The point is that you don't need to, unless you are concerned about people
deliberately producing files with clashing names. And if that *is* your
concern, GetTempFileName() is of no use either, as I've explained
upthread.
Note also that GetTempFileName() is restricted to 65,535 file names *per
user*. There's only one temp directory. Once it's "full" by these
standards, GetTempFileName() will simply fail. Now, I've never seen that
happen on a production system, but if you want to argue that existing
files are a problem, GetTempFileName() would become a problem long before
GUID file names would. In other words: neither has a problem.
My original response recommended to use the Win32 API version of
GetTempFileName, not the .NET version, so the limit is not per user, but per
directory, assuming a fixed prefix.
In the end, without checking, using a new GUID is not guaranteed to work
upon a successful call (without trying to create the temp file to guarantee
the name, and cycling if it exists), although the probability is
astronimically high that it will, versus a successful call to
GetTempFileName, where the result is always guaranteed. For EITHER method,
trying to create the file and cycling to another name is required in order
to guarantee it would work all the time (when the call returns success, that
is).