我需要用.csv扩展名生成一个唯一的临时文件。
我现在做的是
string filepath = System.IO.Path.GetTempFileName().Replace(".tmp", ".csv");
但是,这并不能保证.csv文件是唯一的。
我知道发生碰撞的可能性非常低(特别是如果您考虑到我没有删除.tmp文件的话),但是这段代码对我来说不太好。
当然,我可以手动生成随机文件名,直到我最终找到一个唯一的文件名(这应该不是问题),但我很想知道其他人是否已经找到了处理这个问题的好方法。
唯一的:保证(统计上)唯一的:
string fileName = System.IO.Path.GetTempPath() + Guid.NewGuid().ToString() + ".csv";
(引用维基上关于碰撞概率的文章:
...one's annual risk of being hit by a
meteorite is estimated to be one
chance in 17 billion [19], that means
the probability is about 0.00000000006
(6 × 10−11), equivalent to the odds of
creating a few tens of trillions of
UUIDs in a year and having one
duplicate. In other words, only after
generating 1 billion UUIDs every
second for the next 100 years, the
probability of creating just one
duplicate would be about 50%. The
probability of one duplicate would be
about 50% if every person on earth
owns 600 million UUIDs
编辑:请参阅JaredPar的评论。
在我看来,这里提出的大多数答案都是次优的。最接近的是最初由Brann提出的。
临时文件名必须是
独特的
无冲突(不存在)
原子(在同一操作中创建名称和文件)
很难猜测
由于这些需求,独自编写这样一个野兽并不是一个好主意。聪明的人写IO库时会担心像锁(如果需要的话)等事情。
因此,我认为没有必要重写System.IO.Path.GetTempFileName()。
这个,即使看起来很笨拙,也应该做到:
//Note that this already *creates* the file
string filename1 = System.IO.Path.GetTempFileName()
// Rename and move
filename = filename.Replace(".tmp", ".csv");
File.Move(filename1 , filename);
你也可以选择使用System.CodeDom.Compiler.TempFileCollection。
string tempDirectory = @"c:\\temp";
TempFileCollection coll = new TempFileCollection(tempDirectory, true);
string filename = coll.AddExtension("txt", true);
File.WriteAllText(Path.Combine(tempDirectory,filename),"Hello World");
这里我使用txt扩展名,但你可以指定任何你想要的。我还将keep标志设置为true,以便在使用后保留临时文件。不幸的是,TempFileCollection为每个扩展名创建一个随机文件。如果需要更多临时文件,可以创建TempFileCollection的多个实例。