【问题标题】:Creating a unique temporary directory from pure C in windows在 Windows 中从纯 C 创建一个唯一的临时目录
【发布时间】:2011-06-09 02:33:21
【问题描述】:

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

我本质上是在寻找一个相当于 linux mkdtemp 功能。有一个 C# 答案 here,以及 this question 上的回复 建议使用 Boost。但是由于我使用的是 C,因此这些解决方案不起作用 对我来说。

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

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

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

【问题讨论】:

  • 你最后一段中的想法是行不通的——它会受到竞争条件的影响。

标签: c windows winapi temporary-directory


【解决方案1】:

您可以使用 GetTempPath 返回的内容与 Guid 连接,以确保目录的唯一性。您可以使用 UuidCreate CoCreateGuid Function 创建 Guid。

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

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

【讨论】:

  • 我考虑过使用 GUID 或 UUID,但我看不到如何将它们转换为字符串。进一步挖掘将我带到StringFromGUID2,这可能会奏效,只要它不会生成不能进入文件名的字符?看起来它只会生成十六进制字符串,应该没问题。
  • @Timothy - 标准 guid 格式适用于文件名,但无论如何,由于您不需要这些 guid 格式,因此您不需要 StringFromGUIS2,因为您也可以生成文件名“手动”使用十六进制格式写入的 16 个字节的串联。
【解决方案2】:

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

【讨论】:

  • 这基本上就是mkdtemp 所做的(当然包括重试)。
【解决方案3】:

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

对于递归删除目录树,您可以使用SHFileOperation。或者,您可以使用FindFirstFile/FindNextFileDeleteFileRemoveDirectory 自己进行目录遍历。

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2017-03-06
    • 2013-09-18
    • 1970-01-01
    • 1970-01-01
    • 2010-09-21
    • 2022-11-25
    • 1970-01-01
    相关资源
    最近更新 更多