详细介绍GetTempFileName()

书籍:《Visual C++ 2017从入门到精通》的2.10 文件操作

环境:visual studio 2022

内容:[例 2.53] 读写一个临时文件

1. 功能概述​

GetTempFileName() 是 Windows API 中用于​​生成唯一临时文件名​​的核心函数。其生成的文件名通常用于:

  • 临时存储应用程序运行时的中间数据。
  • 避免文件名冲突(如多线程/多实例程序)。
  • 需要程序结束后手动删除的临时资源。

​2. 函数原型与参数​

​C/C++ 原型​
UINT GetTempFileName(
  LPCTSTR lpPathName,    // 临时文件目录路径
  LPCTSTR lpPrefixString,// 文件名前缀
  UINT    uUnique,       // 唯一性标识(0 表示自动生成)
  LPTSTR  lpTempFileName // 接收生成的文件名缓冲区
);
​参数详解​
参数名类型描述
lpPathNameLPCTSTR临时文件目录路径(需包含终止符 \)。常用 GetTempPath() 获取。
lpPrefixStringLPCTSTR文件名前缀(最多 3 个字符会被使用)。例如前缀为 TMP,则文件名形如 TMP1234.tmp
uUniqueUINT唯一性标识:
0:自动生成唯一编号(基于时间戳 + 随机数)。
- 非零:直接追加该数字到前缀后(不检查唯一性)。
lpTempFileNameLPTSTR接收结果的缓冲区(需 ≥ MAX_PATH 字符)。
​返回值​
  • ​成功​​:返回生成文件名中的唯一数字部分(如 1234)。
  • ​失败​​:返回 0,需通过 GetLastError() 获取错误码。

​3. 文件名生成规则​

  • ​格式​​:<路径>\<前缀><唯一标识>.tmp

    • ​路径​​:由 lpPathName 指定(如 C:\Temp\)。
    • ​前缀​​:取 lpPrefixString 的前 3 个字符(如 TMP)。
    • ​唯一标识​​:
      • 若 uUnique=0:生成 4 位十六进制数(如 A1B2)。
      • 若 uUnique≠0:直接追加该数字(如 1234)。
  • ​示例​​:

    • lpPathName = "C:\Temp\"lpPrefixString = "DATA"uUnique=0 → C:\Temp\DATA1A2B.tmp
    • lpPathName = "C:\Temp\"lpPrefixString = "LOG"uUnique=9999 → C:\Temp\LOG9999.tmp

​4. 使用场景​

  1. ​临时数据存储​​:如缓存计算结果、会话数据。
  2. ​多进程协作​​:避免不同进程生成同名文件。
  3. ​自动化测试​​:创建临时测试文件并自动清理。

​5. 代码示例​

​C++ 示例​
#include <windows.h>
#include <tchar.h>
#include <stdio.h>

int main() {
    TCHAR szTempPath[MAX_PATH] = {0};
    TCHAR szTempFile[MAX_PATH] = {0};

    // 获取临时目录路径
    if (GetTempPath(MAX_PATH, szTempPath) == 0) {
        _tprintf(_T("获取临时路径失败,错误码:%lu\n"), GetLastError());
        return 1;
    }

    // 生成临时文件名
    UINT uResult = GetTempFileName(szTempPath, _T("TMP"), 0, szTempFile);
    if (uResult == 0) {
        _tprintf(_T("生成临时文件名失败,错误码:%lu\n"), GetLastError());
        return 1;
    }

    _tprintf(_T("临时文件路径:%s\n"), szTempFile);

    // 创建并写入文件(可选)
    HANDLE hFile = CreateFile(szTempFile, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
    if (hFile != INVALID_HANDLE_VALUE) {
        const char* szData = "Hello, Temp File!";
        DWORD dwWritten = 0;
        WriteFile(hFile, szData, strlen(szData), &dwWritten, NULL);
        CloseHandle(hFile);
    }

    return 0;
}
​VB 示例​
Private Declare Function GetTempFileName Lib "kernel32" Alias "GetTempFileNameA" _
    (ByVal lpszPath As String, ByVal lpPrefixString As String, _
    ByVal wUnique As Long, ByVal lpTempFileName As String) As Long

Sub Main()
    Dim tempPath As String
    Dim tempFile As String
    Dim result As Long

    ' 获取临时路径
    tempPath = GetTempPath()  ' 需自行实现或调用 API

    ' 生成临时文件名
    result = GetTempFileName(tempPath, "TEST", 0, tempFile)
    If result = 0 Then
        MsgBox "生成临时文件名失败,错误码:" & Err.LastDllError
    Else
        MsgBox "临时文件路径:" & tempFile
    End If
End Sub
​C# 示例​
using System;
using System.IO;
using System.Runtime.InteropServices;

class Program {
    [DllImport("kernel32.dll", CharSet = CharSet.Auto)]
    private static extern uint GetTempFileName(
        string lpPathName,
        string lpPrefixString,
        uint uUnique,
        StringBuilder lpTempFileName);

    static void Main() {
        string tempPath = Path.GetTempPath();
        StringBuilder tempFile = new StringBuilder(260);

        uint result = GetTempFileName(tempPath, "DATA", 0, tempFile);
        if (result == 0) {
            Console.WriteLine("生成临时文件名失败,错误码:" + Marshal.GetLastWin32Error());
        } else {
            Console.WriteLine("临时文件路径:" + tempFile.ToString());
        }
    }
}

​6. 关键注意事项​

  1. ​路径有效性​​:

    • 确保 lpPathName 是有效目录(可通过 GetTempPath() 获取)。
    • 路径长度需 ≤ MAX_PATH - 14(避免缓冲区溢出)。
  2. ​唯一性控制​​:

    • 当 uUnique=0 时,若短时间内生成大量文件(如超过 65535 个),可能失败。
    • 非零 uUnique 需自行确保唯一性。
  3. ​文件清理​​:

    • 生成的临时文件​​不会被系统自动删除​​,需手动调用 DeleteFile 或 File.Delete
  4. ​跨平台限制​​:

    • 仅限 Windows 系统,Linux/macOS 需使用其他方法(如 mkstemp 或 tempfile 模块)。

​7. 错误处理​

错误码含义解决方案
ERROR_BUFFER_OVERFLOW路径超过 MAX_PATH - 14 字符缩短路径或使用绝对路径
ERROR_INVALID_PARAMETER参数无效(如空路径)检查参数合法性
ERROR_SEM_FAILCRITICALOPS资源不足释放资源后重试

​8. 扩展应用​

  • ​批量生成临时文件​​:
    通过循环调用 GetTempFileName() 生成多个文件,适用于测试场景。
  • ​自定义临时目录​​:
    结合 GetTempPath() 和 SetCurrentDirectory() 动态切换目录。

​9. 跨语言对比​

语言函数/方法特点
​C/C++​GetTempFileName()原生 API,灵活控制路径和前缀。
​VB​GetTempFileName API 声明需手动声明外部函数,兼容旧版 VB。
​C#​P/Invoke 调用或 Path.GetTempFileName()后者更简单(返回完整路径),但无法自定义前缀。
​Python​tempfile.mktemp()自动生成唯一文件名,但需注意安全性(避免路径注入)。

通过合理使用 GetTempFileName(),开发者可以高效管理临时资源,同时避免文件名冲突问题。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值