path.GetRandomFileName会每次生成一个唯一的文件名吗?另外,Gettempfilename会产生一个唯一的名称吗?
答案 0 :(得分:8)
在我的系统Path.GetRandomFileName()
上返回8.3格式的短名称。
是否保证永远不会两次返回相同的名称?不,你不能保证,就像你不能用于任何哈希算法一样。只有有限数量的名称,所以最终你会得到重复。
然而,由于Path.GetRandomFileName()
使用加密强大的随机数生成器RNGCryptoServiceProvider
,因此可能性非常低。
总结一下,你无法以严格的方式保证它是独一无二的。但复制的可能性非常低,所以你可以认为它是。
答案 1 :(得分:4)
在这两种情况下,简短的答案都是肯定的 实际上,它将生成11个随机字符,这意味着有(26 +10)^ 11个可能的名称(1.316217e + 17),因此创建相同名称两次的机会不存在,并且出于所有实际目的。
有关详情,建议您阅读this
答案 2 :(得分:0)
从我在https://dotnetfiddle.net/bmFVSX的小提琴中复制Path_SafeGetTempFilename方法应该可以给您带来更多的安全性(但是仍然容易发生低概率的数据争用,可以通过使用自己的临时子文件夹将其最小化):
//.NET's Path.GetTempFilename (https://docs.microsoft.com/en-us/dotnet/api/system.io.path.gettempfilename?view=net-5.0) raises an IOException if the system's temp folder has more than 65535 files
//Following a suggestion from https://github.com/dotnet/sdk/issues/8439
//to use Path.GetTempPath (https://docs.microsoft.com/en-us/dotnet/api/system.io.path.gettemppath?view=net-5.0) to get the system temp folder
//combined via Path.Combine (https://docs.microsoft.com/en-us/dotnet/api/system.io.path.combine?view=net-5.0)
//with GetRandomFilename (https://docs.microsoft.com/en-us/dotnet/api/system.io.path.getrandomfilename?view=net-5.0) instead
//For extra safety cross-checking (in a do/while loop) with File.Exists (https://docs.microsoft.com/en-us/dotnet/api/system.io.file.exists?view=net-5.0) before returning the file
//Using File.WriteAllLines (https://docs.microsoft.com/en-us/dotnet/api/system.io.file.writealllines?view=net-5.0) to create the temp file since that is the original behaviour of GetTempFilename in contrast to GetRandomFilename
//Note: "Path.GetRandomFileName() uses the RNGCryptoServiceProvider which is a cryptographically strong random number generator", quoting https://stackoverflow.com/questions/21684696/will-path-getrandomfilename-generate-a-unique-filename-every-time/21684881#21684881
using System;
using System.Diagnostics;
using System.IO;
public class Program
{
public static string Path_SafeGetTempFileName() {
string filepath; //no need to initialize with empty/null value, the do/while code flow construct will always set a value to filepath
do
{
filepath = Path.Combine(Path.GetTempPath(), Path.GetRandomFileName());
} while (File.Exists(filepath));
try
{
File.WriteAllLines(filepath, new string[]{}); //generate an empty file
}
catch
{
Debug.WriteLine($"Couldn't create empty temporary file: {filepath}");
//TODO: log any failure to generate an empty temp file here
}
//Note: don't do a loop if it fails to create the temp file since it might be failing to access the filesystem for other reasons, which would cause infinite recursion
return filepath;
}
public static void Main()
{
string tempFilePath1 = Path.GetTempFileName();
string tempFilePath2 = Path_SafeGetTempFileName();
Console.WriteLine(tempFilePath1);
Console.WriteLine(tempFilePath2);
}
}
答案 3 :(得分:0)
来自:https://gist.github.com/samcorcos/e65a0f5a5d641dd3a6b5f513b6a911f8
const calculate = (n, k) => {
const exponent = (-k * (k - 1)) / (2 * n)
return 1 - Math.E ** exponent
}
// where `n` is the number of possible unique hashes
// where `k` is the number of values created
// calculate((26 + 10) ** 11, 51436220) => 0.010000000067703074
Path.GetRandomFileName
有 1% 的碰撞几率。