C# path.getrandomfilename是否每次都会生成唯一的文件名?

C# path.getrandomfilename是否每次都会生成唯一的文件名?,c#,random,path,filenames,C#,Random,Path,Filenames,Path.GetRandomFileName是否会每次生成一个唯一的文件名?另外,Path.GetTempFileName会生成唯一的名称吗?在这两种情况下,简短的回答都是肯定的。 实际上,get将生成11个随机字符,这意味着有(26+10)^11个可能的名称(1.316217e+17),因此创建两次相同名称的机会在所有实际用途中都不存在 有关更多信息,我建议您阅读 在我的系统Path.GetRandomFileName()上,相关的以8.3格式返回一个短名称 是否保证不会两次返回相同的名称?不

Path.GetRandomFileName
是否会每次生成一个唯一的文件名?另外,Path.GetTempFileName会生成唯一的名称吗?

在这两种情况下,简短的回答都是肯定的。
实际上,get将生成11个随机字符,这意味着有(26+10)^11个可能的名称(1.316217e+17),因此创建两次相同名称的机会在所有实际用途中都不存在

有关更多信息,我建议您阅读


在我的系统
Path.GetRandomFileName()
上,相关的以8.3格式返回一个短名称

是否保证不会两次返回相同的名称?不,你不能保证这一点,就像你不能保证任何哈希算法一样。只有有限数量的名字,所以最终你会得到一个重复的

但是,这种可能性非常低,因为
Path.GetRandomFileName()
使用
RNGCryptoServiceProvider
,这是一种加密功能强大的随机数生成器

总而言之,你不能严格保证它是独一无二的。但是复制的可能性非常低,所以您可以假设它是。

从我的小提琴在路径上复制\u SafeGetTempFilename方法应该会给您带来更大的安全性(但仍然容易发生低概率的数据竞争,可以通过使用您自己的临时子文件夹将其最小化):

发件人:


>生成的51436220
Path.GetRandomFileName
的冲突概率为1%。大约有一亿个文件名会发生冲突。根据您愿意接受的冲突概率,一百万个文件名可能会让您感到不舒服。可能不适合8.3文件名,但DOS已经死了,所以谁在乎呢?GetRandomFileName有一个与熵无关的次要动机。尽管NTFS支持很长的路径名,但除最新版本外,大多数.NET版本都仅限于MAX_路径。在许多用例中,有必要在环境定义的临时文件夹下创建几个级别的随机文件夹。GetRandomFileName将50+位的熵编码为一个短名称,这使得路径过长错误发生的可能性降低。除此之外,我同意可以遵循相同的逻辑,设计一个使用更多熵的自定义实现。事实上,只有32^11个可能的名称,因为您可以重试,直到获得一个不存在的名称,但仍可能与其他线程发生数据争用(可能使其成为受保护的块),甚至与其他进程更糟
//.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);       
    }
}
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