Probability of already existing file System.IO.Pat

2019-06-26 10:13发布

问题:

Recently I got the exception:

Message:
System.IO.IOException: The file 'C:\Windows\TEMP\635568456627146499.xlsx' already exists.
   at System.IO.__Error.WinIOError(Int32 errorCode, String maybeFullPath)

This was the result of the following code I used for generating file names:

Path.Combine(Path.GetTempPath(), DateTime.Now.Ticks + ".xlsx");

After realising that it is possible to create two files in one Tick, I changed the code to:

Path.Combine(Path.GetTempPath(), Path.GetRandomFileName() + ".xlsx");

But I am still wondering what is the probability of the above exception in the new case?

回答1:

Internally, GetRandomFileName uses RNGCryptoServiceProvider to generate 11-character (name:8+ext:3) string. The string represents a base-32 encoded number, so the total number of possible strings is 3211 or 255.

Assuming uniform distribution, the chances of making a duplicate are about 2-55, or 1 in 36 quadrillion. That's pretty low: for comparison, your chances of winning NY lotto are roughly one million times higher.



回答2:

The probability of getting duplicate names with GetRandomFileName are really low, but if you look at it source here, you see that they don't check if the name is duplicate (They can't because you can't tell the path where this file should be created)

Instead the Path.GetTempFileName return an unique file name inside the Temp directory.
(So removing also the need to build the temp path in your code)
GetTempFileName uses the Win32 API GetTempFileName requesting the creation of an unique file name.
The Win32 API creates the file with a zero length and release the handle. So you don't fall in concurrency scenarios. Better use this one.



回答3:

GetRandomFileName() returns 8.3 char string. This is 11 characters that can vary. Assuming it contains only letters and digits, this gives us an "alphabet" of 36 characters. So the number of variations is least 36^11, which makes the probability of above exception extremely low.



回答4:

I would like to put my answer in comment area rather than here, but I don't have enough reputation to add comment.

For your first snippet, I think you can precheck if file exists or not.

For the second one, code will generate random name but random means you still have tiny teeny possibility to get the exception....but I don't think you need worry about this. Existence check will help.