创建和使用临时文件
应用程序可以使用 GetTempFileName 和 GetTempPath 函数获取临时文件的唯一文件和路径名。 GetTempFileName 函数生成唯一的文件名,GetTempPath 函数检索应在其中创建临时文件的目录的路径。
以下过程介绍了应用程序如何创建临时文件以用于数据操作。
创建和使用临时文件
- 应用程序使用 CreateFile 打开用户提供的源文本文件。
- 应用程序使用 GetTempPath 和 GetTempFileName 函数检索临时文件路径和文件名,然后使用 CreateFile 创建临时文件。
- 应用程序将文本数据块读入缓冲区,使用 CharUpperBuffA 函数将缓冲区内容转换为大写,并将转换后的缓冲区写入临时文件。
- 将所有源文件写入临时文件时,应用程序将关闭这两个文件,并使用 MoveFileEx 函数将临时文件重命名为“allcaps.txt”。
在转到下一步之前,检查前面的每个步骤是否成功,如果发生错误,将显示失败说明。 应用程序将在显示错误消息后立即终止。
请注意,选择文本文件操作只是为了便于演示,可以替换为所需的任何所需数据操作过程。 数据文件可以是任何数据类型,而不仅仅是文本。
GetTempPath 函数从环境变量中检索完全限定的路径字符串,但不提前检查是否存在路径或对该路径的足够访问权限,这是应用程序开发人员的责任。 有关详细信息,请参阅 GetTempPath。 在以下示例中,错误被视为终端条件,应用程序在向标准输出发送描述性消息后退出。 但是,存在许多其他选项,例如提示用户输入临时目录或只是尝试使用当前目录。
注意
GetTempFileName 函数不需要使用 GetTempPath 函数。
以下 C++ 示例演示如何创建用于数据操作的临时文件。
//
// This application opens a file specified by the user and uses
// a temporary file to convert the file to upper case letters.
// Note that the given source file is assumed to be an ASCII text file
// and the new file created is overwritten each time the application is
// run.
//
#include <windows.h>
#include <tchar.h>
#include <stdio.h>
#define BUFSIZE 1024
void PrintError(LPCTSTR errDesc);
int _tmain(int argc, TCHAR *argv[])
{
HANDLE hFile = INVALID_HANDLE_VALUE;
HANDLE hTempFile = INVALID_HANDLE_VALUE;
BOOL fSuccess = FALSE;
DWORD dwRetVal = 0;
UINT uRetVal = 0;
DWORD dwBytesRead = 0;
DWORD dwBytesWritten = 0;
TCHAR szTempFileName[MAX_PATH];
TCHAR lpTempPathBuffer[MAX_PATH];
char chBuffer[BUFSIZE];
LPCTSTR errMsg;
if(argc != 2)
{
_tprintf(TEXT("Usage: %s <file>\n"), argv[0]);
return -1;
}
// Opens the existing file.
hFile = CreateFile(argv[1], // file name
GENERIC_READ, // open for reading
0, // do not share
NULL, // default security
OPEN_EXISTING, // existing file only
FILE_ATTRIBUTE_NORMAL, // normal file
NULL); // no template
if (hFile == INVALID_HANDLE_VALUE)
{
PrintError(TEXT("First CreateFile failed"));
return (1);
}
// Gets the temp path env string (no guarantee it's a valid path).
dwRetVal = GetTempPath(MAX_PATH, // length of the buffer
lpTempPathBuffer); // buffer for path
if (dwRetVal > MAX_PATH || (dwRetVal == 0))
{
PrintError(TEXT("GetTempPath failed"));
if (!CloseHandle(hFile))
{
PrintError(TEXT("CloseHandle(hFile) failed"));
return (7);
}
return (2);
}
// Generates a temporary file name.
uRetVal = GetTempFileName(lpTempPathBuffer, // directory for tmp files
TEXT("DEMO"), // temp file name prefix
0, // create unique name
szTempFileName); // buffer for name
if (uRetVal == 0)
{
PrintError(TEXT("GetTempFileName failed"));
if (!CloseHandle(hFile))
{
PrintError(TEXT("CloseHandle(hFile) failed"));
return (7);
}
return (3);
}
// Creates the new file to write to for the upper-case version.
hTempFile = CreateFile((LPTSTR) szTempFileName, // file name
GENERIC_WRITE, // open for write
0, // do not share
NULL, // default security
CREATE_ALWAYS, // overwrite existing
FILE_ATTRIBUTE_NORMAL,// normal file
NULL); // no template
if (hTempFile == INVALID_HANDLE_VALUE)
{
PrintError(TEXT("Second CreateFile failed"));
if (!CloseHandle(hFile))
{
PrintError(TEXT("CloseHandle(hFile) failed"));
return (7);
}
return (4);
}
// Reads BUFSIZE blocks to the buffer and converts all characters in
// the buffer to upper case, then writes the buffer to the temporary
// file.
do
{
if (ReadFile(hFile, chBuffer, BUFSIZE, &dwBytesRead, NULL))
{
// Replaces lower case letters with upper case
// in place (using the same buffer). The return
// value is the number of replacements performed,
// which we aren't interested in for this demo.
CharUpperBuffA(chBuffer, dwBytesRead);
fSuccess = WriteFile(hTempFile,
chBuffer,
dwBytesRead,
&dwBytesWritten,
NULL);
if (!fSuccess)
{
PrintError(TEXT("WriteFile failed"));
return (5);
}
}
else
{
PrintError(TEXT("ReadFile failed"));
return (6);
}
// Continues until the whole file is processed.
} while (dwBytesRead == BUFSIZE);
// The handles to the files are no longer needed, so
// they are closed prior to moving the new file.
if (!CloseHandle(hFile))
{
PrintError(TEXT("CloseHandle(hFile) failed"));
return (7);
}
if (!CloseHandle(hTempFile))
{
PrintError(TEXT("CloseHandle(hTempFile) failed"));
return (8);
}
// Moves the temporary file to the new text file, allowing for differnt
// drive letters or volume names.
fSuccess = MoveFileEx(szTempFileName,
TEXT("AllCaps.txt"),
MOVEFILE_REPLACE_EXISTING | MOVEFILE_COPY_ALLOWED);
if (!fSuccess)
{
PrintError(TEXT("MoveFileEx failed"));
return (9);
}
else
_tprintf(TEXT("All-caps version of %s written to AllCaps.txt\n"), argv[1]);
return (0);
}
// ErrorMessage support function.
// Retrieves the system error message for the GetLastError() code.
// Note: caller must use LocalFree() on the returned LPCTSTR buffer.
LPCTSTR ErrorMessage(DWORD error)
{
LPVOID lpMsgBuf;
FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER
| FORMAT_MESSAGE_FROM_SYSTEM
| FORMAT_MESSAGE_IGNORE_INSERTS,
NULL,
error,
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
(LPTSTR) &lpMsgBuf,
0,
NULL);
return((LPCTSTR)lpMsgBuf);
}
// PrintError support function.
// Simple wrapper function for error output.
void PrintError(LPCTSTR errDesc)
{
LPCTSTR errMsg = ErrorMessage(GetLastError());
_tprintf(TEXT("\n** ERROR ** %s: %s\n"), errDesc, errMsg);
LocalFree((LPVOID)errMsg);
}