How to Generate unique file names in C#

后端 未结 19 2498
生来不讨喜
生来不讨喜 2020-12-02 05:43

I have implemented an algorithm that will generate unique names for files that will save on hard drive. I\'m appending DateTime: Hours,Minutes,Second an

19条回答
  •  佛祖请我去吃肉
    2020-12-02 06:15

    Here's an algorithm that returns a unique readable filename based on the original supplied. If the original file exists, it incrementally tries to append an index to the filename until it finds one that doesn't exist. It reads the existing filenames into a HashSet to check for collisions so it's pretty quick (a few hundred filenames per second on my machine), it's thread safe too, and doesn't suffer from race conditions.

    For example, if you pass it test.txt, it will attempt to create files in this order:

    test.txt
    test (2).txt
    test (3).txt
    

    etc. You can specify the maximum attempts or just leave it at the default.

    Here's a complete example:

    class Program
    {
        static FileStream CreateFileWithUniqueName(string folder, string fileName, 
            int maxAttempts = 1024)
        {
            // get filename base and extension
            var fileBase = Path.GetFileNameWithoutExtension(fileName);
            var ext = Path.GetExtension(fileName);
            // build hash set of filenames for performance
            var files = new HashSet(Directory.GetFiles(folder));
    
            for (var index = 0; index < maxAttempts; index++)
            {
                // first try with the original filename, else try incrementally adding an index
                var name = (index == 0)
                    ? fileName
                    : String.Format("{0} ({1}){2}", fileBase, index, ext);
    
                // check if exists
                var fullPath = Path.Combine(folder, name);
                if(files.Contains(fullPath))
                    continue;
    
                // try to create the file
                try
                {
                    return new FileStream(fullPath, FileMode.CreateNew, FileAccess.Write);
                }
                catch (DirectoryNotFoundException) { throw; }
                catch (DriveNotFoundException) { throw; }
                catch (IOException) 
                {
                    // Will occur if another thread created a file with this 
                    // name since we created the HashSet. Ignore this and just
                    // try with the next filename.
                } 
            }
    
            throw new Exception("Could not create unique filename in " + maxAttempts + " attempts");
        }
    
        static void Main(string[] args)
        {
            for (var i = 0; i < 500; i++)
            {
                using (var stream = CreateFileWithUniqueName(@"c:\temp\", "test.txt"))
                {
                    Console.WriteLine("Created \"" + stream.Name + "\"");
                }
            }
    
            Console.ReadKey();
        }
    }
    

提交回复
热议问题