兩大檔案操作體系
| 特性 | Win32 API (CreateFile 系) | MFC CFile 類 |
| 層級 | 系統底層、功能最完整 | 封裝層、語法簡潔、例外處理 |
| 句柄型別 | HANDLE | 內部封裝 HANDLE,提供 m_hFile |
| 錯誤處理 | GetLastError() | 拋出 CFileException |
| 文字模式 | 無 (需自行處理 \r\n) | CStdioFile 繼承支援文字模式 |
| 非同步 I/O | 支援 (FILE_FLAG_OVERLAPPED) | 不直接支援 |
| 記憶體對應 | CreateFileMapping | CSharedFile / CMemFile 衍生類 |
一、Win32 API 核心函數詳解
1. CreateFile - 開啟/建立檔案
HANDLE CreateFile(
LPCTSTR lpFileName, // 檔案路徑
DWORD dwDesiredAccess, // GENERIC_READ | GENERIC_WRITE
DWORD dwShareMode, // FILE_SHARE_READ | FILE_SHARE_WRITE
LPSECURITY_ATTRIBUTES lpSA, // 安全屬性,NULL=預設
DWORD dwCreationDisposition, // CREATE_NEW/CREATE_ALWAYS/OPEN_EXISTING/OPEN_ALWAYS/TRUNCATE_EXISTING
DWORD dwFlagsAndAttributes, // FILE_ATTRIBUTE_* | FILE_FLAG_*
HANDLE hTemplateFile // 模板檔案句柄
);
常用建立模式
CREATE_NEW:不存在才建,存在失敗
CREATE_ALWAYS:總是建立新檔,覆蓋舊檔
OPEN_EXISTING:必須存在,否則失敗
OPEN_ALWAYS:存在開啟,不存在建立
TRUNCATE_EXISTING:截斷現有檔案為 0 長度
常用旗標屬性
FILE_FLAG_SEQUENTIAL_SCAN:循序讀取優化 (預設)
FILE_FLAG_RANDOM_ACCESS:隨機存取優化
FILE_FLAG_WRITE_THROUGH:寫入直達磁碟 (資料庫/日誌關鍵)
FILE_FLAG_OVERLAPPED:非同步 I/O
FILE_FLAG_DELETE_ON_CLOSE:關閉時自動刪除 (臨時檔案)
FILE_ATTRIBUTE_TEMPORARY:暫存檔提示,系統盡量保留在快取
2. ReadFile / WriteFile - 核心讀寫
BOOL ReadFile(HANDLE hFile, LPVOID lpBuffer, DWORD nNumberOfBytesToRead,
LPDWORD lpNumberOfBytesRead, LPOVERLAPPED lpOverlapped);
BOOL WriteFile(HANDLE hFile, LPCVOID lpBuffer, DWORD nNumberOfBytesToWrite,
LPDWORD lpNumberOfBytesWritten, LPOVERLAPPED lpOverlapped);
3. SetFilePointer / SetFilePointerEx - 隨機存取
DWORD SetFilePointer(HANDLE hFile, LONG lDistanceToMove,
PLONG lpDistanceToMoveHigh, DWORD dwMoveMethod);
// dwMoveMethod: FILE_BEGIN/FILE_CURRENT/FILE_END
BOOL SetFilePointerEx(HANDLE hFile, LARGE_INTEGER liDistanceToMove,
PLARGE_INTEGER lpNewFilePointer, DWORD dwMoveMethod); // 64-bit 安全
4. GetFileSizeEx - 64-bit 安全取得大小
BOOL GetFileSizeEx(HANDLE hFile, PLARGE_INTEGER lpFileSize);
5. CloseHandle - 關閉句柄
BOOL CloseHandle(HANDLE hObject);
二、MFC CFile 類實戰
繼承體系
CFile (基底,二進位)
├── CStdioFile (文字模式,ReadString/WriteString)
├── CMemFile (記憶體檔案)
└── CSharedFile (共享記憶體檔案)
常用方法
| 方法 | 說明 |
| Open | 開啟檔案,mode: modeRead/modeWrite/modeReadWrite \| modeCreate \| modeNoTruncate \| typeText/binary |
| Read/Write | 二進位讀寫 |
| ReadString/WriteString | CStdioFile 專屬,文字行讀寫 |
| Seek/SeekToBegin/SeekToEnd | 檔案指標移動 |
| GetLength/SetLength | 取得/設定檔案大小 |
| LockRange/UnlockRange | 檔案區域鎖定 |
| Close | 關閉檔案 |
| GetFilePath/GetFileName/GetFileTitle | 路徑資訊 |
異常處理模式
CFile file;
CFileException ex;
if (!file.Open(_T("data.dat"), CFile::modeRead | CFile::shareDenyWrite, &ex)) {
TCHAR msg[256];
ex.GetErrorMessage(msg, 256);
AfxMessageBox(msg);
return;
}
// 正常讀寫...
file.Close();
三、CStdioFile 文字檔處理 (最常用)
CStdioFile file;
file.Open(_T("log.txt"), CFile::modeCreate | CFile::modeWrite | CFile::typeText);
file.WriteString(_T("第一行\r\n"));
file.WriteString(_T("第二行\r\n"));
file.Close();
// 讀取
file.Open(_T("log.txt"), CFile::modeRead | CFile::typeText);
CString line;
while (file.ReadString(line)) {
TRACE(_T("%s"), line);
}
file.Close();
四、進階技巧對比
| 需求 | Win32 API | MFC CFile |
| 大檔案 (>4GB) 隨機存取 | SetFilePointerEx + LARGE_INTEGER | CFile::Seek (內部用 64-bit) |
| 非同步 I/O / IOCP | FILE_FLAG_OVERLAPPED + ReadFileEx | 不支援,需直接用 API |
| 記憶體對應檔案 | CreateFileMapping + MapViewOfFile | CSharedFile (有限) |
| 檔案鎖定 (多進程同步) | LockFileEx | CFile::LockRange |
| 臨時檔案自動清理 | FILE_FLAG_DELETE_ON_CLOSE | 無直接對應,需手動刪除 |
| Unicode 路徑 (>260 字元) | \\?\ 前綴 + CreateFileW | CFile::Open 內部已處理 |
五、選擇建議
- 一般業務邏輯、文字檔、中小型二進位檔:優先
CFile/CStdioFile,程式碼可讀、維護性佳
- 高效能、非同步、大檔案、記憶體對應、系統工具:直接用
Win32 API
- 混合使用:
CFile::m_hFile 公開底層 HANDLE,可隨時呼叫 API 擴充功能
理解兩者關係與優劣,才能在專案中做出最適合的架構決策。
- 上一篇文章: VC++ 修改檔案/資料夾完整屬性:時間戳記、隱藏/唯讀、大小資訊
- 下一篇文章: VC6.0 CSplitterWnd 動態與靜態分割視窗完整實戰:從巢狀分割到 CuteFTP 風格
Copyright ©
程式碼之家 All Rights Reserved