任何人都有一个很好的方法来ATOMICALLY在.net托管代码中创建一个临时目录

本文关键字:创建 一个 托管代码 很好 有一个 方法 net ATOMICALLY 任何人 | 更新日期: 2023-09-27 18:20:02

.net框架有GetTempFileName,它直接进入同名的Windows API过程,据我所知,这是一种线程安全的方法,可以创建一个以前未使用过的名称的临时文件。它非常过时和有限,但据我所知,只要你的临时目录不被填满,它就可以工作。

但我看不出有什么能很好地创建临时文件夹。在一个有争议的并行环境(如web服务器)中,我看不出任何方法可以避免测试文件夹名称是否正在使用和创建文件夹名称之间的竞争条件。我认为这对于非托管的API代码来说是可行的,但这样的解决方案可能会受到机构的抵制。有更好的方法吗?

如果有,它可以扩展回临时文件创建吗,这样我就不必使用GetTempFileName及其四个十六进制数字的变体了?

--对于那些认为这是重复的人来说:链接的另一个问题并没有真正解决线程安全问题。我必须针对线程安全是一个非常严重的问题的情况进行开发——我们可能有32个内核在运行,每个内核都试图创建一批100或1000个临时文件。

--更新:Chess and West的《使用静态分析的安全编程》一书称GetTempFileName"存在固有的潜在种族条件"。所以也许那也不安全。

任何人都有一个很好的方法来ATOMICALLY在.net托管代码中创建一个临时目录

如果您想创建一个唯一的临时目录,Path.GetTempPathGuid.NewGuid的组合应该可以很好地完成任务:

string GetUniqueTempPath()
{
    var tempPath = Path.GetTempPath();
    var uniqueDirectoryName = Guid.NewGuid().ToString();
    var uniqueTempPath = Path.Combine(tempPath, uniqueDirectoryName);
    return uniqueTempPath;
}

GUID被用作路径的一部分这一事实应该会消除任何竞争条件,因为几乎不存在复合目录名,所以在尝试创建它之前不需要(真正的)检查。

@paul kienitz FWIW:根据CreateDirectory()的文档,如果目录已经存在,函数将返回ERROR_ALREADY_EXISTS,这将为您提供冲突的原子检查。因此,如果将随机名称方法(使用CoCreateGuid())与有限次数的重试(例如9次重试)相结合,则可以安全地创建一个新的临时目录。重试将以指数方式将碰撞概率降低到一个甚至满足偏执狂的值。

相关文章: