Will path.getrandomfilename generate a unique filename every time?

前端 未结 3 810
囚心锁ツ
囚心锁ツ 2021-01-17 18:35

Will Path.GetRandomFileName generate a unique filename every single time? Also, what about Path.GetTempFileName - will that generate a unique name?

3条回答
  •  猫巷女王i
    2021-01-17 18:53

    Copying from my fiddle at https://dotnetfiddle.net/bmFVSX the Path_SafeGetTempFilename method should give you a bit more safety (but still is prone to low probability data race that could be minimized by using your own temp subfolder):

    //.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);       
        }
    }
    

提交回复
热议问题