我需要用.csv扩展名生成一个唯一的临时文件。
我现在做的是
string filepath = System.IO.Path.GetTempFileName().Replace(".tmp", ".csv");
但是,这并不能保证.csv文件是唯一的。
我知道发生碰撞的可能性非常低(特别是如果您考虑到我没有删除.tmp文件的话),但是这段代码对我来说不太好。
当然,我可以手动生成随机文件名,直到我最终找到一个唯一的文件名(这应该不是问题),但我很想知道其他人是否已经找到了处理这个问题的好方法。
在我看来,这里提出的大多数答案都是次优的。最接近的是最初由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);
这是生成增量文件名的一种简单但有效的方法。它将直接查看当前文件(您可以轻松地将其指向其他地方),并搜索以YourApplicationName*.txt为基础的文件(同样,您可以轻松地更改该文件)。它将从0000开始,因此第一个文件名将是YourApplicationName0000.txt。如果由于某种原因,文件名在左右部分之间(即不是数字)有垃圾,那么这些文件将通过tryparse调用被忽略。
public static string CreateNewOutPutFile()
{
const string RemoveLeft = "YourApplicationName";
const string RemoveRight = ".txt";
const string searchString = RemoveLeft + "*" + RemoveRight;
const string numberSpecifier = "0000";
int maxTempNdx = -1;
string fileName;
string [] Files = Directory.GetFiles(Directory.GetCurrentDirectory(), searchString);
foreach( string file in Files)
{
fileName = Path.GetFileName(file);
string stripped = fileName.Remove(fileName.Length - RemoveRight.Length, RemoveRight.Length).Remove(0, RemoveLeft.Length);
if( int.TryParse(stripped,out int current) )
{
if (current > maxTempNdx)
maxTempNdx = current;
}
}
maxTempNdx++;
fileName = RemoveLeft + maxTempNdx.ToString(numberSpecifier) + RemoveRight;
File.CreateText(fileName); // optional
return fileName;
}