在 Windows 中获取临时目录名称的最佳方法是什么? 我看到我可以使用 GetTempPath
和 GetTempFileName
来创建临时文件,但是是否有与 Linux / BSD mkdtemp
用于创建临时目录的函数?
What's the best way to get a temp directory name in Windows? I see that I can use GetTempPath
and GetTempFileName
to create a temporary file, but is there any equivalent to the Linux / BSD mkdtemp
function for creating a temporary directory?
发布评论
评论(10)
不,没有与 mkdtemp 等效的东西。 最好的选择是使用 GetTempPath 和 GetRandomFileName。
您将需要与此类似的代码:
No, there is no equivalent to mkdtemp. The best option is to use a combination of GetTempPath and GetRandomFileName.
You would need code similar to this:
我破解了 Path.GetTempFileName() 来在磁盘上提供一个有效的伪随机文件路径,然后删除该文件,并创建一个具有相同文件路径的目录。
根据 Chris 对 Scott Dorman 答案的评论,这避免了检查文件路径在一段时间内或循环中是否可用的需要。
如果您确实需要一个加密安全的随机名称,您可能需要调整 Scott 的答案以使用 while 或 do 循环来继续尝试在磁盘上创建路径。
I hack
Path.GetTempFileName()
to give me a valid, pseudo-random filepath on disk, then delete the file, and create a directory with the same file path.This avoids the need for checking if the filepath is available in a while or loop, per Chris' comment on Scott Dorman's answer.
If you truly need a cryptographically secure random name, you may want to adapt Scott's answer to use a while or do loop to keep trying to create a path on disk.
自 .NET 7 起:
使用文件夹名称的自定义前缀
Since .NET 7:
Using a custom prefix for the folder name
我使用了一些答案并以这种方式实现了 GetTmpDirectory 方法。
I used some of the answers and implemented
GetTmpDirectory
method this way.我喜欢使用 GetTempPath()、GUID 创建函数,如 CoCreateGuid() 和 CreateDirectory()。
GUID 被设计为具有很高的唯一性概率,而且某人也不太可能手动创建与 GUID 形式相同的目录(如果他们这样做,则 CreateDirectory() 将失败,表明其存在。)
I like to use GetTempPath(), a GUID-creation function like CoCreateGuid(), and CreateDirectory().
A GUID is designed to have a high probability of uniqueness, and it's also highly improbable that someone would manually create a directory with the same form as a GUID (and if they do then CreateDirectory() will fail indicating its existence.)
@克里斯。 我也对临时目录可能已经存在的远程风险很着迷。 关于随机性和加密强度的讨论也不完全令我满意。
我的方法建立在这样一个基本事实之上:操作系统不得允许两次创建文件的调用都成功。 有点令人惊讶的是,.NET 设计者选择隐藏目录的 Win32 API 功能,这使得这变得更加容易,因为当您尝试第二次创建目录时,它确实会返回错误。 这是我使用的:
您可以决定非托管 p/invoke 代码的“成本/风险”是否值得。 大多数人会说不是,但至少你现在有了选择。
CreateParentFolder() 留给学生作为练习。 我使用 Directory.CreateDirectory()。 获取目录的父目录时要小心,因为它在根目录下为空。
@Chris. I too was obsessed with the remote risk that a temporary directory might already exist. The discussions about random and cryptographically strong don’t completely satisfy me either.
My approach builds on the fundamental fact that the O/S must not allow 2 calls to create a file to both succeed. It is a little surprising that .NET designers chose to hide the Win32 API functionality for directories, which makes this much easier, because it does return an error when you attempt to create a directory for the second time. Here is what I use:
You get to decide whether the "cost/risk" of unmanaged p/invoke code is worth it. Most would say it is not, but at least you now have a choice.
CreateParentFolder() is left as an exercise to the student. I use Directory.CreateDirectory(). Be careful getting the parent of a directory, since it is null when at the root.
我通常使用这个:
如果你想绝对确定这个目录名不会存在于临时路径中,那么你需要检查这个唯一的目录名是否存在,并尝试创建另一个目录名(如果确实存在)。
但这种基于 GUID 的实现就足够了。 我对这种情况没有任何问题的经验。 一些 MS 应用程序也使用基于 GUID 的临时目录。
I usually use this:
If you want to be absolutely sure that this directory name will not exists in temp path then you need to check if this unique directory name exists and try to create other one if it really exists.
But this GUID-based implementation is sufficient. I have no experience with any problem in this case. Some MS applications uses GUID based temp directories too.
这是解决临时目录名称冲突问题的更暴力的方法。 这不是一种万无一失的方法,但它显着减少了文件夹路径冲突的机会。
人们可以潜在地将其他进程或程序集相关信息添加到目录名称中,以降低发生冲突的可能性,尽管使此类信息在临时目录名称上可见可能并不理想。 人们还可以混合时间相关字段的组合顺序,以使文件夹名称看起来更加随机。 我个人更喜欢保持这种方式,因为这样我在调试过程中更容易找到它们。
Here is a somewhat more brute-force approach to resolving the collision problem for temporary directory names. It is not an infallible approach, but it reduces significantly the chances of a folder path collision.
One could potentially add other process or assembly related information to the directory name to make the collision even less likely, although making such an information visible on the temporary directory name might not be desirable. One could also mix the order with which the time-related fields are combined to make the folder names look more random. I personally prefer to leave it that way simply because it is easier for me to find them all during debugging.
如上所述,Path.GetTempPath() 是一种方法。 如果用户设置了 TEMP 环境变量。
如果您计划使用临时目录作为在应用程序中保存数据的方法,您可能应该考虑使用 IsolatedStorage 作为配置/状态/等的存储库...
As mentioned above, Path.GetTempPath() is one way to do it. You could also call Environment.GetEnvironmentVariable("TEMP") if the user has a TEMP environment variable set up.
If you are planning on using the temp directory as a means of persisting data in the application, you probably should look at using IsolatedStorage as a repository for configuration/state/etc...
GetTempPath 是正确的方法; 我不确定您对这种方法的担忧是什么。 然后,您可以使用 CreateDirectory 来创建它。
GetTempPath is the correct way of doing it; I'm not sure what your concern about this method is. You can then use CreateDirectory to make it.