Windows 下应优先使用 GetTempPath 获取临时路径,它自动处理环境变量与注册表回退并确保路径存在可写;返回宽字符且以反斜杠结尾,需传入至少 MAX_PATH 长度缓冲区,并用 GetDiskFreeSpaceEx 查询所在卷剩余空间。

Windows 下用 GetTempPath 获取默认临时路径
Windows 提供了系统级 API 直接返回当前用户的默认临时目录,不需要手动拼接环境变量或硬编码路径。GetTempPath 是最稳妥的方式,它会优先读取 TEMP 或 TMP 环境变量, fallback 到用户配置目录,最终保证路径存在且可写。
注意:GetTempPath 返回的是以反斜杠结尾的字符串,长度上限为 MAX_PATH(260 字符),所以务必传入足够大的缓冲区:
WCHAR tempPath[MAX_PATH];
DWORD len = GetTempPath(MAX_PATH, tempPath);
if (len == 0 || len >= MAX_PATH) {
// 错误处理:可能权限不足或缓冲区太小
}- 不要用
std::getenv("TEMP")替代 —— 它不处理注册表 fallback,也不做路径有效性检查 - 返回路径是宽字符(
WCHAR),若需 UTF-8,用WideCharToMultiByte(CP_UTF8, ...)转换 - 该路径不保证有写权限,使用前建议用
GetFileAttributes检查FILE_ATTRIBUTE_DIRECTORY
Linux/macOS 用 std::getenv + std::filesystem::temp_directory_path
C++17 的 std::filesystem::temp_directory_path() 是跨平台首选,但它在 Linux/macOS 上实际行为依赖 libc 实现:优先查 TMPDIR,再查 TEMP/TMP,最后 fallback 到 /tmp。但部分旧版 libstdc++(如 GCC 8 前)可能未实现或返回空路径。
更可靠的做法是组合使用:
立即学习“C++免费学习笔记(深入)”;
std::string getTempDir() {
if (const char* tmp = std::getenv("TMPDIR")) return tmp;
if (const char* tmp = std::getenv("TEMP")) return tmp;
if (const char* tmp = std::getenv("TMP")) return tmp;
return "/tmp";
}-
std::filesystem::temp_directory_path()可能抛std::filesystem::filesystem_error,需 try/catch - 返回路径不带尾部斜杠,自行拼接文件名时要加
/ - macOS 上
/var/folders/xxx是沙盒临时路径,普通程序应优先用NSHomeDirectory()+"/Library/Caches/"(Objective-C 交互场景)
用 GetDiskFreeSpaceEx(Windows)或 statvfs(POSIX)查剩余容量
获取磁盘剩余空间必须基于路径所在卷,不能只看临时目录本身 —— 它可能是个符号链接或挂载点。
Windows 下推荐 GetDiskFreeSpaceEx,它返回的是 ULARGE_INTEGER,避免 32 位整数溢出:
ULARGE_INTEGER freeBytes;
if (GetDiskFreeSpaceEx(tempPath, nullptr, nullptr, &freeBytes)) {
uint64_t free = freeBytes.QuadPart; // 单位:字节
}POSIX 系统用 statvfs,注意 f_bavail * f_frsize 是非特权用户可用空间,f_bfree * f_frsize 是总空闲空间:
struct statvfs buf;
if (statvfs("/tmp", &buf) == 0) {
uint64_t avail = static_cast<uint64_t>(buf.f_bavail) * buf.f_frsize;
}- Windows 的
GetDiskFreeSpaceEx要求路径是目录,且必须存在;若tempPath不存在,先调用CreateDirectory或 fallback 到"C:\\" - Linux 下
/tmp可能是 tmpfs 内存文件系统,statvfs返回的f_blocks是内存页数,不是磁盘真实容量 - macOS 的 APFS 卷支持稀疏文件和空间共享,
statvfs的结果可能与 Finder 显示不一致
跨平台封装时最容易被忽略的细节
临时路径和磁盘容量看似简单,但混合使用时容易踩坑:比如在 Windows 上拿到 C:\Users\xxx\AppData\Local\Temp\,却用 statvfs 去查 /tmp;或者没处理符号链接导致卷判断错误。
- 务必先用
GetFinalPathNameByHandle(Windows)或realpath(POSIX)解析临时路径的真实卷根路径 - 剩余空间单位统一转成字节再做比较,避免 KB/MB 换算误差
- 权限检查不能只靠路径存在性 ——
access(path.c_str(), W_OK)或GetFileAttributes+FILE_ATTRIBUTE_READONLY更准 - C++20 的
std::filesystem::space可替代手写statvfs,但 MSVC 2019 及更早版本不支持,需条件编译


















