c++ - 在 C++ 上使用 GetTempFileName 函数生成随机文件名

标签 c++ winapi

我想使用 GetTempFileName函数生成随机文件名,但在调用函数时不创建文件本身。我想使用该函数来使用名称本身(不带扩展名),以便稍后我可以创建一个具有该特定名称的文件夹。由于没有创建文件夹的类似函数,我只想获取 GetTempFileName 创建的字符串,以便稍后创建文件夹。

LPTSTR wzTemp = new TCHAR[MAX_PATH];
GetTempFileName(strTemp, 0, 0, wzTemp);

CString tempFolder;
tempFolder = wzTemp;

这是我的尝试,但在 GetTempFileName 之后文件被创建。

知道我该如何调整吗?

最佳答案

GetTempFileName负责创建文件。如果您想创建一个唯一的目录,则必须编写自己的实现。使用 GetTempFileName,然后删除文件,并在其位置创建同名目录注定会失败,因为 TOCTOU种族。

创建唯一名称的标准解决方案是使用 GUID 的字符串表示形式。您可以调用UuidCreate , 其次是 UuidToString得到一个。

如果 36 个字符在您的情况下不方便使用,您将需要根据不太独特的算法(如系统时间)和重试策略编写自己的实现。

例如,这里有一个实现,它使用系统时间的字符串表示形式,表示为 64 位十进制数。这导致了一个字符串表示,即最多 19 个字符宽。

#include <Windows.h>
#include <iostream>
#include <string>
#include <system_error>

std::wstring GetTempDir(std::wstring const& root_dir) {
    while (true) {
        ::SYSTEMTIME st{};
        ::GetSystemTime(&st);

        ::FILETIME ft{};
        if (!::SystemTimeToFileTime(&st, &ft)) {
            auto error_code{ ::GetLastError() };
            throw std::system_error(error_code, std::system_category(),
                                    "SystemTimeToFileTime()");
        }

        ULARGE_INTEGER ft_uli{ ft.dwLowDateTime, ft.dwHighDateTime };
        auto dir_name{ std::to_wstring(ft_uli.QuadPart) };
        auto dir_name_full{ root_dir + dir_name };
        if (::CreateDirectoryW(dir_name_full.c_str(), nullptr)) {
            return dir_name_full;
        }
        else {
            auto error_code{ ::GetLastError() };
            if (error_code != ERROR_ALREADY_EXISTS) {
                throw std::system_error(error_code, std::system_category(),
                                        "CreateDirectoryW()");
            }
        }
    }
}

此函数返回它创建的临时目录的完全限定路径,如果不能则抛出异常。它需要一个指向根目录的字符串,包括尾随反斜杠。如果目录已经存在,它会不断尝试,直到可以创建目录。

请特别注意,没有竞争条件。如果函数成功,则目录已经创建。

它可以像下面的例子那样被调用:

int main() {
    wchar_t path[MAX_PATH + 1]{};
    ::GetTempPathW(_countof(path), path);

    auto temp_dir{ GetTempDir(path) };
    std::wcout << L"Temporary directory created: " << temp_dir << std::endl;
}

关于c++ - 在 C++ 上使用 GetTempFileName 函数生成随机文件名,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49288470/

相关文章:

c++ - 如何从类中访问函数?

c++ - CryptProtectData API 提供的加密有多安全?

windows - 使用 Windows API 更改文件权限

c++ - 如何在 Rust winapi 编程中使用 COM VARIANT?

c++ - 如何追踪 COM 内存泄漏

c++ - std::function std::bind with lambda 重载歧义

c++ - 如果构造函数抛出, `new` 分配的内存会发生什么?

c++ - 模板类的 VS 编译器错误

c++ - Windows 7:超越 C++ std::this_thread::sleep_for

c++ - 我们可以从设备句柄中获取设备对象的详细信息/名称吗