我需要用.csv扩展名生成一个唯一的临时文件。

我现在做的是

string filepath = System.IO.Path.GetTempFileName().Replace(".tmp", ".csv");

但是,这并不能保证.csv文件是唯一的。

我知道发生碰撞的可能性非常低(特别是如果您考虑到我没有删除.tmp文件的话),但是这段代码对我来说不太好。

当然,我可以手动生成随机文件名,直到我最终找到一个唯一的文件名(这应该不是问题),但我很想知道其他人是否已经找到了处理这个问题的好方法。


当前回答

我混合@Maxence和@Mitch小麦答案记住,我想要GetTempFileName方法的语义(文件名是创建的新文件的名称)添加扩展名首选。

string GetNewTempFile(string extension)
{
    if (!extension.StartWith(".")) extension="." + extension;
    string fileName;
    bool bCollisions = false;
    do {
        fileName = Path.Combine(System.IO.Path.GetTempPath(), Guid.NewGuid().ToString() + extension);
        try
        {
            using (new FileStream(fileName, FileMode.CreateNew)) { }
            bCollisions = false;
        }
        catch (IOException)
        {
            bCollisions = true;
        }
    }
    while (bCollisions);
    return fileName;
}

其他回答

简单的c#函数:

public static string GetTempFileName(string extension = "csv")
{
    return Path.ChangeExtension(Path.GetTempFileName(), extension);
}

唯一的:保证(统计上)唯一的:

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的评论。

试试这个功能…

public static string GetTempFilePathWithExtension(string extension) {
  var path = Path.GetTempPath();
  var fileName = Path.ChangeExtension(Guid.NewGuid().ToString(), extension);
  return Path.Combine(path, fileName);
}

它将返回一个完整的路径和您选择的扩展名。

注意,它不能保证产生唯一的文件名,因为从技术上讲,其他人可能已经创建了该文件。然而,有人猜出你的应用产生的下一个guid并创建它的机会非常非常低。假设这是唯一的是很安全的。

这就是我所做的:

string tStamp = String.Format("{0:yyyyMMdd.HHmmss}", DateTime.Now);
string ProcID = Process.GetCurrentProcess().Id.ToString();
string tmpFolder = System.IO.Path.GetTempPath();
string outFile = tmpFolder + ProcID + "_" + tStamp + ".txt";

为什么不检查文件是否存在?

string fileName;
do
{
    fileName = System.IO.Path.GetTempPath() + Guid.NewGuid().ToString() + ".csv";
} while (System.IO.File.Exists(fileName));