在 Windows 中从纯 C 创建一个唯一的临时目录

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/6287475/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-15 17:01:55  来源:igfitidea点击:

Creating a unique temporary directory from pure C in windows

cwindowswinapitemporary-directory

提问by Timothy Jones

I'd like to create a unique temporary directory in Windows from some C code (not C++ or C#). I want to do this so that I can put some temp files in the directory, and then delete them all easily when I'm done (by removing the directory recursively).

我想从一些 C 代码(不是 C++ 或 C#)在 Windows 中创建一个唯一的临时目录。我想这样做,以便我可以在目录中放置一些临时文件,然后在完成后轻松删除它们(通过递归删除目录)。

I'm essentially looking for an equivalent of the linux mkdtempfunction. There is a C# answer here, and responses on this questionsuggest using Boost. But since I'm using C, those solutions don't work for me.

我本质上是在寻找等效的 linux mkdtemp函数。有一个C#的答案在这里,并在回应这个问题使用Boost建议。但是由于我使用的是 C,这些解决方案对我不起作用。

The best I've been able to come up with so far is to use GetTempFileNamefollowed by CreateDirectory, but the problem there is that if I ask GetTempFileNameto create a unique file name, it will also create the file (which I don't want, since I want to make a directory instead).

到目前为止我能想到的最好的方法是使用 GetTempFileName后跟CreateDirectory,但问题是如果我要求 GetTempFileName创建一个唯一的文件名,它也会创建文件(我不想要,因为我想创建一个目录)。

Relatedly, there's GetTempPath, which returns the location of the user's temp folder from environment variables - but since I want to create my own directory that I can safely delete later, I still need to create a directory inside any path it would return.

相关地,有 GetTempPath,它从环境变量返回用户临时文件夹的位置 - 但由于我想创建我自己的目录,以后可以安全地删除,我仍然需要在它返回的任何路径中创建一个目录。

It looks like if I want a unique directory to be created, I'll have to create a temp file, get the name, delete it, and then create a directory with the same name - which sounds very messy. Any other ideas?

看起来如果我想创建一个唯一的目录,我必须创建一个临时文件,获取名称,删除它,然后创建一个具有相同名称的目录 - 这听起来很混乱。还有其他想法吗?

采纳答案by Simon Mourier

You can use what GetTempPathreturns concatenated with a Guid to ensure uniqueness of the directory. You can create a Guid using UuidCreate or CoCreateGuid Function.

您可以使用 whatGetTempPath与 Guid 连接的返回值来确保目录的唯一性。您可以使用UuidCreateCoCreateGuid Function创建 Guid 。

To delete recursively the directory, there is an example here in pure C: How to remove directory recursively?based on FindFirstFile, FindNextFile, DeleteFile and RemoveDirectory.

要递归删除目录,纯C中有一个例子:How to remove directory recursively?基于 FindFirstFile、FindNextFile、DeleteFile 和RemoveDirectory

There is also SHFileOperationbut it's more heavyweight and is based on the Windows Shell functions, and the Shell DLLs are not always wanted, especially if you're writing server code.

还有SHFileOperation但它更重量级并且基于 Windows Shell 函数,并且并不总是需要 Shell DLL,尤其是在您编写服务器代码时。

回答by R.. GitHub STOP HELPING ICE

Use GetTempPaththen CreateDirectorywith a random name under it, optionally retrying if CreateDirectoryfails due to it already existing. But if your name generation is good enough, the likelihood of a collision with an existing name is much smaller than the likelihood of a blackhat guessing your password or even your private key, so you might as well ignore it.

GetTempPath然后CreateDirectory在其下使用随机名称,如果CreateDirectory由于它已经存在而失败,则可以选择重试。但是如果你的名字生成足够好,与现有名字冲突的可能性远小于黑帽猜测你的密码甚至你的私钥的可能性,所以你不妨忽略它。

回答by Adam Rosenfield

Use _tempnamtmpnam_sto create a filename that doesn't exist yet, and then use CreateDirectoryto create the directory. There's technically a race condition if you do this, in that another process could potentially create a file or directory with that name in the time in between when you generate the filename and when you create the directory, but the odds of that are rather unlikely. To protect against that, you can loop until you succeed.

使用创造了一个并不存在的文件名,然后使用创建的目录。如果您这样做,在技术上存在竞争条件,因为另一个进程可能会在您生成文件名和创建目录之间的时间内创建一个具有该名称的文件或目录,但这种可能性很小。为了防止这种情况,您可以循环直到成功。_tempnamtmpnam_sCreateDirectory

For recursively removing a directory tree, you can use SHFileOperation. Alternatively, you can do the directory traversal yourself with FindFirstFile/FindNextFile, DeleteFile, and RemoveDirectory.

要递归删除目录树,您可以使用SHFileOperation. 或者,你可以自己做目录遍历与FindFirstFile/ FindNextFileDeleteFileRemoveDirectory

If you want to remove the directory automatically upon exiting, register a function using atexit. This will only work for normal program termination (i.e. via the exitfunction or via returning from main/WinMain). This will not work for abnormal program termination (e.g. via abort, an access violation, someone else calling TerminateProcess, etc.).

如果要在退出时自动删除目录,请使用atexit. 这仅适用于正常的程序终止(即通过exit函数或通过从main/返回WinMain)。这不适用于异常程序终止(例如,通过abort、访问冲突、其他人调用TerminateProcess等)。