C# 有没有人找到一种在.net托管代码中以原子方式创建临时目录的好方法?
net framework有GetTempFileName,它直接指向同名的Windows API过程,据我所知,这是一种线程安全的方法,可以使用以前未使用的名称创建临时文件。它已经过时了,而且很有限,但据我所知,只要你不让临时目录被填满,它就可以工作 但我看不到任何东西能够很好地创建临时文件夹。在有争议的并行环境(如web服务器)中,我看不到任何方法可以避免测试文件夹名是否正在使用和创建文件夹名之间的竞争。我认为这在非托管API代码中是可行的,但这种解决方案可能会受到机构的抵制。有更好的办法吗 如果有,是否可以将其扩展回临时文件创建,这样我就不必使用GetTempFileName及其四个十六进制数字的变体 --对于那些认为这是重复的人来说:链接的另一个问题并没有真正解决线程安全问题。我必须针对线程安全是一个非常严重的问题的情况进行开发——我们可能有32个内核运行,每个内核都试图创建成批的100或1000个临时文件C# 有没有人找到一种在.net托管代码中以原子方式创建临时目录的好方法?,c#,.net,C#,.net,net framework有GetTempFileName,它直接指向同名的Windows API过程,据我所知,这是一种线程安全的方法,可以使用以前未使用的名称创建临时文件。它已经过时了,而且很有限,但据我所知,只要你不让临时目录被填满,它就可以工作 但我看不到任何东西能够很好地创建临时文件夹。在有争议的并行环境(如web服务器)中,我看不到任何方法可以避免测试文件夹名是否正在使用和创建文件夹名之间的竞争。我认为这在非托管API代码中是可行的,但这种解决方案可能会受到机构的抵制。有更好的办法吗
--更新:Chess和West的《静态分析的安全编程》一书说GetTempFileName“受到固有的潜在竞争条件的影响”。因此,这可能也不安全。如果您想创建一个唯一的临时目录,和的组合应该可以很好地完成这一任务:
string GetUniqueTempPath()
{
var tempPath = Path.GetTempPath();
var uniqueDirectoryName = Guid.NewGuid().ToString();
var uniqueTempPath = Path.Combine(tempPath, uniqueDirectoryName);
return uniqueTempPath;
}
GUID被用作路径的一部分这一事实应该可以消除任何竞争条件,因为复合目录名几乎不可能存在,因此在尝试创建它之前不需要(实际)检查。我想,这将有很大的可能性避免冲突,尽管没有保证。但它确实给了我一个问题的文件方面的想法,尽管不是目录方面:我们不能在创建时自动测试和设置,除非使用
GetTempFileName
,但看起来可以这样做的一个操作是RenameFile
。因此,如果您在GetTempFileName提供的小空间中创建了一个唯一的名称,则可以通过重命名它,将其提升到GUID名称提供的大空间中,并保证不合并。(继续)但这并不能解决目录的情况。。。如果我有threadsafe临时目录,这可能会使文件的名称空间问题变得毫无意义,因为我不必在我的私人文件夹中竞争名称;它声明“非常确定地说,此函数返回一个唯一的值–在相同或任何其他系统(网络或非网络)上的任何其他调用都不应返回相同的值。”。简言之,您应该是冲突安全的:)如果我们有一种原子方法来实际测试文件系统,而不是仅仅假设有足够的熵,那里可能没有匹配项,我仍然会觉得安全得多。@Paul使用GUID应该足够了,但如果您对此如此偏执,然后查看这个答案,如果这是单个服务器上的单个进程,那么可能是重复的,因为您不只是使用原子方式生成序列名称,比如说Interlocked.Increment
?如有必要,将它们嵌套在干净的随机目录中(创建一次)。而不是单个进程。