跳转至

文件操作API

概述

Windows提供了丰富的文件操作API,用于创建、读取、写入、删除文件以及管理目录。这些API支持同步和异步操作。

文件创建与打开

CreateFile - 创建或打开文件

CreateFile函数

创建或打开文件、目录、物理磁盘、卷、控制台缓冲区等对象。

C++
1
2
3
4
5
6
7
8
9
HANDLE CreateFile(
    LPCSTR                lpFileName,           // 文件名
    DWORD                 dwDesiredAccess,      // 访问模式
    DWORD                 dwShareMode,          // 共享模式
    LPSECURITY_ATTRIBUTES lpSecurityAttributes, // 安全属性
    DWORD                 dwCreationDisposition,// 创建方式
    DWORD                 dwFlagsAndAttributes, // 文件属性和标志
    HANDLE                hTemplateFile         // 模板文件句柄
);

访问模式

模式 说明
GENERIC_READ 0x80000000 读取权限
GENERIC_WRITE 0x40000000 写入权限
GENERIC_EXECUTE 0x20000000 执行权限
GENERIC_ALL 0x10000000 所有权限

共享模式

模式 说明
0 不共享
FILE_SHARE_READ 允许读共享
FILE_SHARE_WRITE 允许写共享
FILE_SHARE_DELETE 允许删除共享

创建方式

方式 说明
CREATE_NEW 创建新文件,存在则失败
CREATE_ALWAYS 创建新文件,存在则覆盖
OPEN_EXISTING 打开现有文件,不存在则失败
OPEN_ALWAYS 打开文件,不存在则创建
TRUNCATE_EXISTING 打开并清空文件

文件属性和标志

标志 说明
FILE_ATTRIBUTE_NORMAL 普通文件
FILE_ATTRIBUTE_READONLY 只读文件
FILE_ATTRIBUTE_HIDDEN 隐藏文件
FILE_ATTRIBUTE_SYSTEM 系统文件
FILE_ATTRIBUTE_ARCHIVE 存档文件
FILE_FLAG_OVERLAPPED 异步操作
FILE_FLAG_DELETE_ON_CLOSE 关闭时删除

示例

C++
// 创建新文件
HANDLE hFile = CreateFile(
    "C:\\test.txt",
    GENERIC_WRITE,
    0,
    NULL,
    CREATE_ALWAYS,
    FILE_ATTRIBUTE_NORMAL,
    NULL
);

if (hFile == INVALID_HANDLE_VALUE) {
    printf("CreateFile failed: %d\n", GetLastError());
    return -1;
}

// 打开现有文件用于读取
HANDLE hFile = CreateFile(
    "C:\\test.txt",
    GENERIC_READ,
    FILE_SHARE_READ,
    NULL,
    OPEN_EXISTING,
    FILE_ATTRIBUTE_NORMAL,
    NULL
);

文件读写

ReadFile - 读取文件

C++
1
2
3
4
5
6
7
BOOL ReadFile(
    HANDLE       hFile,             // 文件句柄
    LPVOID       lpBuffer,          // 缓冲区
    DWORD        nNumberOfBytesToRead, // 要读取的字节数
    LPDWORD      lpNumberOfBytesRead,  // 实际读取的字节数
    LPOVERLAPPED lpOverlapped       // 异步操作结构
);

示例

C++
1
2
3
4
5
6
7
8
char buffer[1024];
DWORD bytesRead;

BOOL success = ReadFile(hFile, buffer, sizeof(buffer), &bytesRead, NULL);
if (success && bytesRead > 0) {
    buffer[bytesRead] = '\0';
    printf("Read %d bytes: %s\n", bytesRead, buffer);
}

WriteFile - 写入文件

C++
1
2
3
4
5
6
7
BOOL WriteFile(
    HANDLE       hFile,                // 文件句柄
    LPCVOID      lpBuffer,             // 数据缓冲区
    DWORD        nNumberOfBytesToWrite, // 要写入的字节数
    LPDWORD      lpNumberOfBytesWritten, // 实际写入的字节数
    LPOVERLAPPED lpOverlapped          // 异步操作结构
);

示例

C++
1
2
3
4
5
6
7
const char* data = "Hello, World!";
DWORD bytesWritten;

BOOL success = WriteFile(hFile, data, strlen(data), &bytesWritten, NULL);
if (success) {
    printf("Written %d bytes\n", bytesWritten);
}

完整读写示例

C++
#include <windows.h>
#include <stdio.h>

int main() {
    // 创建文件
    HANDLE hFile = CreateFile(
        "C:\\test.txt",
        GENERIC_READ | GENERIC_WRITE,
        0,
        NULL,
        CREATE_ALWAYS,
        FILE_ATTRIBUTE_NORMAL,
        NULL
    );
    
    if (hFile == INVALID_HANDLE_VALUE) {
        printf("CreateFile failed: %d\n", GetLastError());
        return -1;
    }
    
    // 写入数据
    const char* data = "Hello, Windows API!\n";
    DWORD bytesWritten;
    WriteFile(hFile, data, strlen(data), &bytesWritten, NULL);
    
    // 移动文件指针到开头
    SetFilePointer(hFile, 0, NULL, FILE_BEGIN);
    
    // 读取数据
    char buffer[1024];
    DWORD bytesRead;
    ReadFile(hFile, buffer, sizeof(buffer) - 1, &bytesRead, NULL);
    buffer[bytesRead] = '\0';
    
    printf("Read: %s\n", buffer);
    
    // 关闭文件
    CloseHandle(hFile);
    
    return 0;
}

文件指针操作

SetFilePointer - 设置文件指针

C++
1
2
3
4
5
6
DWORD SetFilePointer(
    HANDLE hFile,           // 文件句柄
    LONG   lDistanceToMove, // 移动距离
    PLONG  lpDistanceToMoveHigh, // 高32位距离
    DWORD  dwMoveMethod     // 移动方式
);

移动方式: - FILE_BEGIN:从文件开头 - FILE_CURRENT:从当前位置 - FILE_END:从文件末尾

示例

C++
// 移动到文件开头
SetFilePointer(hFile, 0, NULL, FILE_BEGIN);

// 移动到文件末尾
SetFilePointer(hFile, 0, NULL, FILE_END);

// 从当前位置前移100字节
SetFilePointer(hFile, 100, NULL, FILE_CURRENT);

// 移动到大文件位置(> 4GB)
LARGE_INTEGER li;
li.QuadPart = 0x100000000LL;  // 4GB
SetFilePointer(hFile, li.LowPart, &li.HighPart, FILE_BEGIN);

SetFilePointerEx - 扩展设置文件指针

C++
1
2
3
4
5
6
BOOL SetFilePointerEx(
    HANDLE          hFile,
    LARGE_INTEGER   liDistanceToMove,
    PLARGE_INTEGER  lpNewFilePointer,
    DWORD           dwMoveMethod
);

示例

C++
1
2
3
LARGE_INTEGER offset, newPos;
offset.QuadPart = 1024;
SetFilePointerEx(hFile, offset, &newPos, FILE_BEGIN);

文件属性

GetFileSize - 获取文件大小

C++
1
2
3
4
DWORD GetFileSize(
    HANDLE  hFile,
    LPDWORD lpFileSizeHigh
);

示例

C++
DWORD dwSize = GetFileSize(hFile, NULL);
printf("File size: %d bytes\n", dwSize);

GetFileSizeEx - 扩展获取文件大小

C++
1
2
3
4
BOOL GetFileSizeEx(
    HANDLE          hFile,
    PLARGE_INTEGER  lpFileSize
);

示例

C++
1
2
3
LARGE_INTEGER size;
GetFileSizeEx(hFile, &size);
printf("File size: %lld bytes\n", size.QuadPart);

GetFileAttributes - 获取文件属性

C++
1
2
3
DWORD GetFileAttributes(
    LPCTSTR lpFileName
);

返回属性: - FILE_ATTRIBUTE_READONLY - FILE_ATTRIBUTE_HIDDEN - FILE_ATTRIBUTE_SYSTEM - FILE_ATTRIBUTE_DIRECTORY - FILE_ATTRIBUTE_ARCHIVE - FILE_ATTRIBUTE_NORMAL - INVALID_FILE_ATTRIBUTES:失败

示例

C++
DWORD attrs = GetFileAttributes("C:\\test.txt");
if (attrs == INVALID_FILE_ATTRIBUTES) {
    printf("GetFileAttributes failed: %d\n", GetLastError());
} else {
    if (attrs & FILE_ATTRIBUTE_READONLY) {
        printf("File is read-only\n");
    }
    if (attrs & FILE_ATTRIBUTE_HIDDEN) {
        printf("File is hidden\n");
    }
    if (attrs & FILE_ATTRIBUTE_DIRECTORY) {
        printf("It is a directory\n");
    }
}

SetFileAttributes - 设置文件属性

C++
1
2
3
4
BOOL SetFileAttributes(
    LPCTSTR lpFileName,
    DWORD   dwFileAttributes
);

示例

C++
1
2
3
4
5
6
// 设置为只读和隐藏
SetFileAttributes("C:\\test.txt", FILE_ATTRIBUTE_READONLY | FILE_ATTRIBUTE_HIDDEN);

// 取消只读属性
DWORD attrs = GetFileAttributes("C:\\test.txt");
SetFileAttributes("C:\\test.txt", attrs & ~FILE_ATTRIBUTE_READONLY);

GetFileTime - 获取文件时间

C++
1
2
3
4
5
6
BOOL GetFileTime(
    HANDLE     hFile,
    LPFILETIME lpCreationTime,
    LPFILETIME lpLastAccessTime,
    LPFILETIME lpLastWriteTime
);

SetFileTime - 设置文件时间

C++
1
2
3
4
5
6
BOOL SetFileTime(
    HANDLE           hFile,
    const FILETIME   *lpCreationTime,
    const FILETIME   *lpLastAccessTime,
    const FILETIME   *lpLastWriteTime
);

示例

C++
1
2
3
4
5
6
7
8
9
FILETIME creation, access, write;
GetFileTime(hFile, &creation, &access, &write);

// 转换为SYSTEMTIME
SYSTEMTIME stCreation;
FileTimeToSystemTime(&creation, &stCreation);
printf("Created: %04d-%02d-%02d %02d:%02d:%02d\n",
    stCreation.wYear, stCreation.wMonth, stCreation.wDay,
    stCreation.wHour, stCreation.wMinute, stCreation.wSecond);

目录操作

CreateDirectory - 创建目录

C++
1
2
3
4
BOOL CreateDirectory(
    LPCTSTR                lpPathName,
    LPSECURITY_ATTRIBUTES  lpSecurityAttributes
);

示例

C++
1
2
3
if (!CreateDirectory("C:\\MyDir", NULL)) {
    printf("CreateDirectory failed: %d\n", GetLastError());
}

RemoveDirectory - 删除目录

C++
1
2
3
BOOL RemoveDirectory(
    LPCTSTR lpPathName
);

示例

C++
RemoveDirectory("C:\\MyDir");

GetCurrentDirectory - 获取当前目录

C++
1
2
3
4
DWORD GetCurrentDirectory(
    DWORD  nBufferLength,
    LPTSTR lpBuffer
);

示例

C++
1
2
3
char buffer[MAX_PATH];
GetCurrentDirectory(MAX_PATH, buffer);
printf("Current directory: %s\n", buffer);

SetCurrentDirectory - 设置当前目录

C++
1
2
3
BOOL SetCurrentDirectory(
    LPCTSTR lpPathName
);

示例

C++
SetCurrentDirectory("C:\\Windows");

文件查找

FindFirstFile - 开始查找文件

C++
1
2
3
4
HANDLE FindFirstFile(
    LPCTSTR           lpFileName,
    LPWIN32_FIND_DATA lpFindFileData
);

FindNextFile - 继续查找

C++
1
2
3
4
BOOL FindNextFile(
    HANDLE            hFindFile,
    LPWIN32_FIND_DATA lpFindFileData
);

FindClose - 关闭查找句柄

C++
1
2
3
BOOL FindClose(
    HANDLE hFindFile
);

WIN32_FIND_DATA结构

C++
typedef struct _WIN32_FIND_DATA {
    DWORD    dwFileAttributes;
    FILETIME ftCreationTime;
    FILETIME ftLastAccessTime;
    FILETIME ftLastWriteTime;
    DWORD    nFileSizeHigh;
    DWORD    nFileSizeLow;
    DWORD    dwReserved0;
    DWORD    dwReserved1;
    TCHAR    cFileName[MAX_PATH];
    TCHAR    cAlternateFileName[14];
} WIN32_FIND_DATA;

示例 - 列出目录内容

C++
#include <windows.h>
#include <stdio.h>

void ListDirectory(const char* path) {
    WIN32_FIND_DATA findData;
    char searchPath[MAX_PATH];
    
    sprintf(searchPath, "%s\\*.*", path);
    
    HANDLE hFind = FindFirstFile(searchPath, &findData);
    if (hFind == INVALID_HANDLE_VALUE) {
        printf("FindFirstFile failed: %d\n", GetLastError());
        return;
    }
    
    do {
        if (findData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) {
            printf("[DIR] %s\n", findData.cFileName);
        } else {
            printf("[FILE] %s (%d bytes)\n", 
                findData.cFileName, 
                findData.nFileSizeLow);
        }
    } while (FindNextFile(hFind, &findData));
    
    FindClose(hFind);
}

int main() {
    ListDirectory("C:\\");
    return 0;
}

示例 - 递归查找文件

C++
#include <windows.h>
#include <stdio.h>

void FindFilesRecursive(const char* path, const char* pattern) {
    WIN32_FIND_DATA findData;
    char searchPath[MAX_PATH];
    
    // 查找文件
    sprintf(searchPath, "%s\\%s", path, pattern);
    HANDLE hFind = FindFirstFile(searchPath, &findData);
    
    if (hFind != INVALID_HANDLE_VALUE) {
        do {
            if (!(findData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)) {
                printf("%s\\%s\n", path, findData.cFileName);
            }
        } while (FindNextFile(hFind, &findData));
        FindClose(hFind);
    }
    
    // 递归查找子目录
    sprintf(searchPath, "%s\\*.*", path);
    hFind = FindFirstFile(searchPath, &findData);
    
    if (hFind != INVALID_HANDLE_VALUE) {
        do {
            if (findData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) {
                if (strcmp(findData.cFileName, ".") != 0 && 
                    strcmp(findData.cFileName, "..") != 0) {
                    char subPath[MAX_PATH];
                    sprintf(subPath, "%s\\%s", path, findData.cFileName);
                    FindFilesRecursive(subPath, pattern);
                }
            }
        } while (FindNextFile(hFind, &findData));
        FindClose(hFind);
    }
}

int main() {
    FindFilesRecursive("C:\\Projects", "*.cpp");
    return 0;
}

文件删除与移动

DeleteFile - 删除文件

C++
1
2
3
BOOL DeleteFile(
    LPCTSTR lpFileName
);

示例

C++
1
2
3
if (!DeleteFile("C:\\test.txt")) {
    printf("DeleteFile failed: %d\n", GetLastError());
}

MoveFile - 移动文件

C++
1
2
3
4
BOOL MoveFile(
    LPCTSTR lpExistingFileName,
    LPCTSTR lpNewFileName
);

MoveFileEx - 扩展移动文件

C++
1
2
3
4
5
BOOL MoveFileEx(
    LPCTSTR lpExistingFileName,
    LPCTSTR lpNewFileName,
    DWORD   dwFlags
);

标志: - MOVEFILE_REPLACE_EXISTING:替换现有文件 - MOVEFILE_COPY_ALLOWED:允许复制(如果移动失败) - MOVEFILE_DELAY_UNTIL_REBOOT:重启时执行

示例

C++
1
2
3
4
5
6
7
8
// 移动文件
MoveFile("C:\\old.txt", "C:\\new.txt");

// 移动并替换
MoveFileEx("C:\\old.txt", "C:\\new.txt", MOVEFILE_REPLACE_EXISTING);

// 重命名
MoveFile("C:\\old.txt", "C:\\renamed.txt");

CopyFile - 复制文件

C++
1
2
3
4
5
BOOL CopyFile(
    LPCTSTR lpExistingFileName,
    LPCTSTR lpNewFileName,
    BOOL    bFailIfExists
);

示例

C++
1
2
3
4
5
// 复制文件,目标存在则失败
CopyFile("C:\\source.txt", "C:\\dest.txt", TRUE);

// 复制文件,覆盖现有文件
CopyFile("C:\\source.txt", "C:\\dest.txt", FALSE);

文件锁定

LockFile - 锁定文件区域

C++
1
2
3
4
5
6
7
BOOL LockFile(
    HANDLE hFile,
    DWORD  dwFileOffsetLow,
    DWORD  dwFileOffsetHigh,
    DWORD  nNumberOfBytesToLockLow,
    DWORD  nNumberOfBytesToLockHigh
);

UnlockFile - 解锁文件区域

C++
1
2
3
4
5
6
7
BOOL UnlockFile(
    HANDLE hFile,
    DWORD  dwFileOffsetLow,
    DWORD  dwFileOffsetHigh,
    DWORD  nNumberOfBytesToUnlockLow,
    DWORD  nNumberOfBytesToUnlockHigh
);

示例

C++
1
2
3
4
5
6
7
// 锁定文件的前1024字节
LockFile(hFile, 0, 0, 1024, 0);

// 访问锁定区域...

// 解锁
UnlockFile(hFile, 0, 0, 1024, 0);

参考资料