임시 파일 만들기 및 사용

애플리케이션은 GetTempFileNameGetTempPath 함수를 사용하여 임시 파일의 고유한 파일 및 경로 이름을 가져올 수 있습니다. GetTempFileName 함수는 고유한 파일 이름을 생성하고 GetTempPath 함수는 임시 파일을 만들어야 하는 디렉터리의 경로를 검색합니다.

다음 절차에서는 애플리케이션이 데이터 조작 목적으로 임시 파일을 만드는 방법을 설명합니다.

임시 파일을 만들고 사용하려면

  1. 애플리케이션은 CreateFile을 사용하여 사용자가 제공한 원본 텍스트 파일을 엽니다.
  2. 애플리케이션은 GetTempPathGetTempFileName 함수를 사용하여 임시 파일 경로 및 파일 이름을 검색한 다음, CreateFile을 사용하여 임시 파일을 만듭니다.
  3. 애플리케이션은 텍스트 데이터 블록을 버퍼로 읽고 CharUpperBuffA 함수를 사용하여 버퍼 내용을 대문자로 변환한 다음, 변환된 버퍼를 임시 파일에 씁니다.
  4. 모든 원본 파일이 임시 파일에 기록되면 애플리케이션은 두 파일을 모두 닫고 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);
}