Bra*_*ann 265 .net c# temporary-files
我需要生成一个扩展名为.csv的唯一临时文件.
我现在做的是
string filename = System.IO.Path.GetTempFileName().Replace(".tmp", ".csv");
Run Code Online (Sandbox Code Playgroud)
但是,这并不能保证我的.csv文件是唯一的.
我知道我遇到碰撞的可能性非常低(特别是如果你认为我没有删除.tmp文件),但这段代码对我来说并不好看.
当然我可以手动生成随机文件名,直到我最终找到一个独特的文件名(这不应该是一个问题),但我很想知道其他人是否找到了一个很好的方法来处理这个问题.
Mit*_*eat 340
保证(统计上)唯一:
string fileName = System.IO.Path.GetTempPath() + Guid.NewGuid().ToString() + ".csv";
Run Code Online (Sandbox Code Playgroud)
(引用维基文章中有关碰撞的可能性:
......一个被陨石击中的年度风险估计是170亿[19]中的一次机会,这意味着概率约为0.00000000006(6×10-11),相当于创造几十的几率.一年内数万亿的UUID并且有一个副本.换句话说,只有在接下来的100年中每秒产生10亿UUID之后,创建一个副本的概率大约为50%.如果地球上每个人拥有6亿UUID,则一次重复的概率约为50%
编辑:另请参阅JaredPar的评论.
Jar*_*Par 54
试试这个功能......
public static string GetTempFilePathWithExtension(string extension) {
var path = Path.GetTempPath();
var fileName = Guid.NewGuid().ToString() + extension;
return Path.Combine(path, fileName);
}
Run Code Online (Sandbox Code Playgroud)
它将返回一个包含您选择的扩展名的完整路径.
请注意,不能保证生成唯一的文件名,因为其他人可能已经在技术上已经创建了该文件.然而,有人猜测你的应用程序产生的下一个guid并创建它的可能性非常低.假设这将是独一无二的,这是非常安全的.
Max*_*nce 42
public static string GetTempFileName(string extension)
{
int attempt = 0;
while (true)
{
string fileName = Path.GetRandomFileName();
fileName = Path.ChangeExtension(fileName, extension);
fileName = Path.Combine(Path.GetTempPath(), fileName);
try
{
using (new FileStream(fileName, FileMode.CreateNew)) { }
return fileName;
}
catch (IOException ex)
{
if (++attempt == 10)
throw new IOException("No unique temporary file name is available.", ex);
}
}
}
Run Code Online (Sandbox Code Playgroud)
注意:这与Path.GetTempFileName类似.创建一个空文件以保留文件名.在Path.GetRandomFileName()生成冲突的情况下,它会进行10次尝试;
Meh*_*ras 18
您也可以使用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");
Run Code Online (Sandbox Code Playgroud)
这里我使用了txt扩展名,但你可以指定你想要的任何内容.我还将keep标志设置为true,以便临时文件在使用后保留.不幸的是,TempFileCollection为每个扩展创建一个随机文件.如果需要更多临时文件,可以创建多个TempFileCollection实例.
为什么不检查文件是否存在?
string fileName;
do
{
fileName = System.IO.Path.GetTempPath() + Guid.NewGuid().ToString() + ".csv";
} while (System.IO.File.Exists(fileName));
Run Code Online (Sandbox Code Playgroud)
C++的GetTempFileName的MSDN文档讨论了您的问题并回答了它:
GetTempFileName无法保证文件名是唯一的.
仅使用uUnique参数的低16位.如果lpPathName和lpPrefixString参数保持不变,这会将GetTempFileName限制为最多65,535个唯一文件名.
由于用于生成文件名的算法,GetTempFileName在创建具有相同前缀的大量文件时可能表现不佳.在这种情况下,建议您根据GUID构造唯一的文件名.
小智 6
怎么样:
Path.Combine(Path.GetTempPath(), DateTime.Now.Ticks.ToString() + "_" + Guid.NewGuid().ToString() + ".csv")
Run Code Online (Sandbox Code Playgroud)
计算机在同一时刻生成相同的Guid是极不可能的.我在这里看到的唯一弱点是性能影响DateTime.Now.Ticks将添加.
您还可以执行以下操作
string filename = Path.ChangeExtension(Path.GetTempFileName(), ".csv");
Run Code Online (Sandbox Code Playgroud)
这也按预期工作
string filename = Path.ChangeExtension(Path.GetTempPath() + Guid.NewGuid().ToString(), ".csv");
Run Code Online (Sandbox Code Playgroud)