首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> C語言 >> 關於C語言

C語言大文件高效讀寫:Windows 記憶體映射檔 實戰詳解

     編輯:關於C語言

痛點:傳統 I/O 面對大文件的無力

處理幾十 MB 至數 GB 文件時,fread/ReadFile 等傳統方式涉及:用戶態/核心態切換、資料拷貝(核心緩衝→用戶緩衝)、頻繁系統調用。CPU、記憶體、I/O 三重壓力,效能急劇下降。

解決方案:Memory-Mapped Files (記憶體映射檔)

將文件直接映射至進程虛擬地址空間,以指標方式直接存取文件內容。OS 自動處理頁面調度、預讀、寫回,實現零拷貝、隨機存取、共享記憶體等優勢。

核心 API 流程

  1. CreateFile 取得文件句柄
  2. CreateFileMapping 建立映射對象
  3. MapViewOfFile 映射視圖至位址空間,獲得指標 lpBase
  4. 直接操作 lpBase 指標讀寫資料
  5. UnmapViewOfFile、CloseHandle 清理

實戰案例:超大索引文件鍵值查找

文件格式:KEY=VALUE\r\n,25 萬行、15 MB。傳統 map<string,string> 佔用 70+ MB 記憶體、載入極慢。
映射檔方案:不載入容器,直接指標掃描。

關鍵代碼片段

HANDLE hFile = CreateFile("C:/test.tsr", GENERIC_READ|GENERIC_WRITE, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
HANDLE hMap = CreateFileMapping(hFile, NULL, PAGE_READWRITE, 0, 0, NULL);
SYSTEM_INFO si; GetSystemInfo(&si);
DWORD granularity = si.dwAllocationGranularity;
DWORD dwSizeHigh; 
LONGLONG fileSize = GetFileSize(hFile, &dwSizeHigh);
fileSize |= ((LONGLONG)dwSizeHigh << 32);
CloseHandle(hFile);

DWORD viewSize = (fileSize < 1000*granularity) ? (DWORD)fileSize : 1000*granularity;
TCHAR* pView = (TCHAR*)MapViewOfFile(hMap, FILE_MAP_ALL_ACCESS, 0, 0, viewSize);

// 查找函數:純指標操作,無額外記憶體分配
string GetValue(const TCHAR* base, const TCHAR* key) {
    TCHAR* p1 = strstr(base, key);
    if (!p1) return "";
    TCHAR* p2 = strstr(p1, "\r\n");
    if (p2) *p2 = '\0';
    string val = p1 + strlen(key) + 1; // 跳過 "KEY="
    if (p2) *p2 = '\r'; // 還原
    return val;
}

// 使用
cout << GetValue(pView, "SEU07201213") << endl;

// 清理
UnmapViewOfFile(pView);
CloseHandle(hMap);

效能實測對比

方案記憶體佔用查找耗時 (25萬行)
STL map 預載入70+ MB極慢(含建構開銷)
Memory Mapped File + 指標掃描近 0 額外進程記憶體< 1 秒

注意事項與最佳實踐

  • 分塊映射:超大文件(> 幾百 MB)分段映射,避免 32 位進程虛擬地址空間耗盡。
  • 對齊粒度:MapViewOfFile 偏移量需為系統分配粒度(通常 64KB)倍數。
  • 並發安全:多進程寫入需同步(Mutex/Interlocked),單寫多讀較安全。
  • 異常處理:SEH 保護指標存取,防止頁面錯誤導致崩潰。

總結

記憶體映射檔是 Windows 大文件處理的利器:**以虛擬記憶體機制替代手動緩衝管理**,實現高效、低記憶體佔用、代碼簡潔的文件隨機存取。掌握此技術,輕松應對 GB 級文本/二進制文件處理場景。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved