已有文件System.IO.Path.GetRandomFileName()的概率

最近我得到了例外:

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

这是我用于生成文件名的以下代码的结果:

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

在意识到可以在一个Tick中创建两个文件之后,我将代码更改为:

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

但我仍然想知道新案件中上述例外的可能性是多少?

在内部, GetRandomFileName使用RNGCryptoServiceProvider生成11个字符(名称:8 + ext:3)字符串。 该字符串表示基数为32的编码数,因此可能的字符串总数为32 11或2 55

假设均匀分布,复制的机会大约是2 -55 ,或者是36万亿分之一。 这相当低:相比之下,你赢得纽约乐透的机会大约高出一百万倍。

使用GetRandomFileName获取重复名称的可能性非常低,但是如果你在这里查看它的来源 ,你会看到他们不检查名称是否重复(他们不能因为你不能告诉这个文件的路径)应该创建)

而是Path.GetTempFileName在Temp目录中返回唯一的文件名。
(因此也删除了在代码中构建临时路径的需要)
GetTempFileName使用Win32 API GetTempFileName请求创建唯一的文件名。
Win32 API创建长度为零的文件并释放句柄。 所以你不要陷入并发场景。 更好地利用这个。

GetRandomFileName()返回8.3 char字符串。 这是11个可以变化的字符。 假设它只包含字母和数字,这给我们一个36个字符的“字母”。 因此,变化的数量最少为36 ^ 11,这使得上述exception的概率极低。

我想把我的答案放在评论区而不是这里,但我没有足够的声誉来添加评论。

对于您的第一个代码段,我认为您可以预先检查文件是否存在。

对于第二个,代码将生成随机名称,但随机意味着你仍然有很小的可能性来获得exception….但我认为你不需要担心这个。 存在检查会有所帮助。