繁体   English   中英

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

[英]Use GetTempFileName function to generate random file name on C++

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

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

CString tempFolder;
tempFolder = wzTemp;

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

知道我该如何调整吗?

GetTempFileName负责创建文件。 如果要创建唯一的目录,则必须编写自己的实现。 使用TOPTOU竞赛,使用GetTempFileName ,然后删除文件,并在其位置创建具有相同名称的目录注定会失败。

创建唯一名称的标准解决方案是使用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;
}

您可以删除文件,从生成的名称中删除扩展名,然后创建文件夹。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM