前言
Win32 API 提供了豐富的文件操作函數族。本文按功能分類整理 基礎 I/O、屬性/時間/大小、路徑/複製/移動/刪除、臨時文件、指針控制、鎖定/解鎖、壓縮、內存映射 等核心 API,附帶參數說明、常見標誌、錯誤碼與最佳實踐,作為開發速查手冊。
一、基礎 I/O 操作 (核心四件套)
| API | 用途 | 關鍵參數 | 返回/備註 |
CreateFile | 創建/打開文件、設備、管道、郵槽 | lpFileName, dwDesiredAccess (GENERIC_READ/WRITE), dwShareMode (FILE_SHARE_READ), lpSecurityAttributes, dwCreationDisposition (CREATE_ALWAYS/OPEN_EXISTING...), dwFlagsAndAttributes (FILE_ATTRIBUTE_NORMAL, FILE_FLAG_OVERLAPPED...), hTemplateFile | 成功返回 HANDLE,失敗 INVALID_HANDLE_VALUE。通往文件世界的大門。 |
ReadFile | 同步/異步讀取字節 | hFile, lpBuffer, nNumberOfBytesToRead, lpNumberOfBytesRead, lpOverlapped | 同步時 lpOverlapped=NULL。異步需 FILE_FLAG_OVERLAPPED + OVERLAPPED 結構。 |
WriteFile | 同步/異步寫入字節 | 參數同 ReadFile | 寫入位置由文件指針或 OVERLAPPED.Offset 決定。 |
CloseHandle | 關閉文件/設備/對象句柄 | hObject | 引用計數歸零時真正關閉。必須成對調用。 |
二、文件屬性、時間、大小查詢
| API | 功能 | 關鍵點 |
GetFileTime | 獲取創建/最後訪問/最後寫入時間 | 需 CreateFile 句柄。輸出 FILETIME (UTC, 100ns 間隔)。 |
SetFileTime | 設置上述三個時間 | 需 FILE_WRITE_ATTRIBUTES 權限。 |
GetFileSize / GetFileSizeEx | 獲取文件大小 | GetFileSize 返回低 32 位,高 32 位需 lpFileSizeHigh;推薦 GetFileSizeEx 直接得 LARGE_INTEGER (64 位)。 |
GetFileAttributes / GetFileAttributesEx | 獲取屬性 (只讀/隱藏/系統/存檔/目錄/壓縮/加密/離線/稀疏/重解析點) | Ex 版本返回 WIN32_FILE_ATTRIBUTE_DATA 包含時間/大小,單次調用獲取更多信息。 |
SetFileAttributes | 設置屬性 | 不能修改 FILE_ATTRIBUTE_DIRECTORY 等系統屬性。 |
GetFileInformationByHandle | 一次性獲取所有信息 | 返回 BY_HANDLE_FILE_INFORMATION:屬性、時間、大小、卷序列號、文件索引 (唯一標識)、鏈接數。最全面。 |
三、路徑、複製、移動、刪除、臨時文件
| API | 功能 | 注意事項 |
GetFullPathName | 獲取完整路徑 | 僅當文件在當前目錄下結果正確;真正路徑用 GetModuleFileName (模塊) 或 GetFinalPathNameByHandle (句柄)。 |
CopyFile / CopyFileEx | 複製文件 | 不支持目錄。Ex 支持進度回調、可取消、重啟標誌 (COPY_FILE_RESTARTABLE)。 |
MoveFileEx | 移動/重命名文件或目錄 | 標誌:MOVEFILE_REPLACE_EXISTING, MOVEFILE_COPY_ALLOWED (跨卷自動複製刪除), MOVEFILE_DELAY_UNTIL_REBOOT (重啟執行)。Win2000+ 支持跨卷。 |
DeleteFile | 刪除文件 | 不支持目錄 (用 RemoveDirectory)。只讀文件需先 SetFileAttributes 除去只讀。 |
GetTempPath | 獲取臨時目錄路徑 | 返回如 C:\Users\xxx\AppData\Local\Temp\。 |
GetTempFileName | 在臨時目錄創建唯一文件 | 生成 ~XXX.tmp,返回文件名。調用者負責刪除。 |
四、文件指針控制 (隨機訪問)
| API | 功能 | 關鍵參數 |
SetFilePointer | 移動指針 (32 位) | hFile, lDistanceToMove, lpDistanceToMoveHigh (NULL=不處理高位), dwMoveMethod (FILE_BEGIN/CURRENT/END)。不支持 >4GB。 |
SetFilePointerEx | 移動指針 (64 位) | hFile, liDistanceToMove (LARGE_INTEGER), lpNewFilePointer, dwMoveMethod。首選。 |
五、文件鎖定與解鎖 (區域並發控制)
| API | 功能 | 適用場景 |
LockFile / LockFileEx | 鎖定文件區域 (排他/共享) | Ex 支持 LOCKFILE_EXCLUSIVE_LOCK, LOCKFILE_FAIL_IMMEDIATELY (非阻塞)、OVERLAPPED 異步。實現多進程同步、區域獨佔寫入。 |
UnlockFile / UnlockFileEx | 解除鎖定 | 必須與鎖定參數完全匹配 (偏移、長度)。 |
機制:強制鎖 (Mandatory),嘗試讀寫鎖定區域的其他進程會阻塞或報錯 ERROR_LOCK_VIOLATION。支持同一文件不同區域並發操作。
六、文件壓縮 API (LZ 擴展庫, 32 位)
| API | 功能 | 備註 |
LZOpenFile | 打開壓縮文件讀取 | 返回 LZHANDLE,非標準 HANDLE。 |
LZSeek | 定位壓縮文件位置 | |
LZRead | 讀取並解壓數據 | |
LZClose | 關閉壓縮文件 | |
LZCopy | 複製並解壓到目標文件 | |
GetExpandedName | 從壓縮文件獲取原始文件名 | |
創建壓縮文件:命令行工具 compress.exe (系統自帶)。現代替代:Cabinet API (FCI/FDI)、Zlib、LZMA SDK、Windows Compression API (MSZIP/LZX)。
七、文件內存映射 (大文件/共享內存/高性能 I/O)
| API | 功能 | 流程 |
CreateFileMapping | 創建/打開文件映射對象 | hFile, lpAttributes, flProtect (PAGE_READONLY/READWRITE), dwMaximumSizeHigh/Low, lpName。hFile=INVALID_HANDLE_VALUE 創建共享內存 (無文件)。 |
MapViewOfFile / MapViewOfFileEx | 將映射視圖映射到進程地址空間 | 返回基址 LPVOID。Ex 可指定映射地址。參數:hMap, dwDesiredAccess (FILE_MAP_READ/WRITE/COPY), dwFileOffsetHigh/Low, dwNumberOfBytesToMap (0=整個映射)。 |
UnmapViewOfFile | 取消映射視圖 | 寫入會自動刷新到文件 (延遲)。 |
FlushViewOfFile | 強制刷新視圖變更到磁盤 | 確保數據持久化。 |
優勢:系統管理分頁調度,大文件隨機訪問無需手動緩衝;多進程共享內存 (INVALID_HANDLE_VALUE + 名稱) 極快;注意:映射大小受限於進程地址空間 (32 位進程 ~2GB),64 位無壓力。
八、最佳實踐清單
- 句柄管理:
CreateFile → 操作 → CloseHandle,異常路徑也要關閉 (RAII 封裝 CAutoHandle/unique_handle)。
- 共享模式:
FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE 盡量開放,避免「文件被佔用」錯誤。
- 異步 I/O:高性能場景用
FILE_FLAG_OVERLAPPED + GetOverlappedResult/IOCP,避免線程阻塞。
- 大文件:
GetFileSizeEx + SetFilePointerEx + ReadFile/WriteFile (64 位偏移)。
- 編碼:文件名用 Unicode API (
CreateFileW),內容按協議編碼 (UTF-8/GBK) 自行轉換。
- 安全性:
SECURITY_ATTRIBUTES 設置 DACL 控制訪問權限;敏感數據寫入前加密。
- 錯誤處理:
GetLastError() 立即獲取,轉換為可讀字符串 (FormatMessage) 記錄日誌。
結語
Win32 文件 API 設計遵循「內核對象 + 句柄 + 同步/異步」模型。掌握 CreateFile 權限/共享/創建標誌組合、ReadFile/WriteFile 同步異步雙模、SetFilePointerEx 64 位定位、LockFileEx 區域並發、CreateFileMapping/MapViewOfFile 內存映射,即可應對 99% 文件操作場景。現代 C++ 建議封裝為 RAII 類或使用 std::filesystem (C++17) / Windows::Storage (WinRT) 簡化高層邏輯。