內存映射文件

 Windows上,內存映射文件,使得大文件的讀寫不會消耗太多的內存,也減少了頻繁的cpu指令。另外,windows上的進程間共享數據,也是通過內存映射文件的方式來實現。
剛好又遇到這個需求,需要在服務器上一次載入幾十兆大小的文件,每個文件大約有100萬條數據。所以溫習一下這塊內容。
使用內存映射文件,需要按下列操作步驟操作:
1,打開一個文件對象,也就是文件句柄了。
2,創建一個文件映射對象 。
3,獲取文件映射對象在進程地址空間的指針。
當完成對內存映射文件操作時,執行下面這些步驟清理內存:
1,告訴系統從你的進程的地址空間中撤消文件映射內核對象的映像。
2,關閉文件映射對象。
3,關閉文件句柄。
內存映射可以高效的對大文件進行讀寫操作,可以這樣理解,這個文件在物理磁盤上的存儲空間被作爲虛擬內存使用了,你讀寫這塊內存區域,就相當於讀寫文件。在效率上,比I/O文件系統高了很多。win32上的進程間消息傳遞SendMessage和PostMessage都是用到這種方法。
實際上如果只是單純使用它,就不必深究原理,否則需要去看《Windows核心編程》。
代碼是硬道理:
假設在E盤有一個測試文件test.txt,內容如下:

  1. #include "windows.h" 
  2. #include "stdio.h" 
  3.   
  4. int main() 
  5.     //文件對象 
  6.     TCHAR  STR[] = "hello world!"
  7.     HANDLE hFile = CreateFile("E:\\test.txt"
  8.     GENERIC_READ | GENERIC_WRITE, 
  9.     0, 
  10.     NULL, 
  11.     OPEN_ALWAYS, 
  12.     FILE_ATTRIBUTE_NORMAL, 
  13.     NULL); 
  14.     //映射對象 
  15.     HANDLE hFileMapping = CreateFileMapping(hFile, 
  16.     NULL, 
  17.     PAGE_READWRITE, 
  18.     0, 
  19.     0, 
  20.     NULL); 
  21.     //這裏賦值了2個文件映射的指針,地址從文件頭開始 
  22.     TCHAR *pbFile1 = (TCHAR *)MapViewOfFile(hFileMapping, FILE_MAP_WRITE, 0, 0, 0); 
  23.     TCHAR *pbFile2 = (TCHAR *)MapViewOfFile(hFileMapping, FILE_MAP_WRITE, 0, 0, 0); 
  24.     /* 
  25.     輸出字符串的內容,可以看到的是,把整個文件當作字符串輸出了。 
  26.     當然,如果文件中含有'\0'的字符,你看不到全部文件內容的輸出。 
  27.     */ 
  28.     //兩個輸出的結果是一樣的 
  29.     printf("%s\n", pbFile1); 
  30.     printf("%s\n", pbFile2); 
  31.     /* 
  32.     下面的操作是往這個pbFile1指向的地址寫入點自定義的內容, 
  33.     然後比較pbFile2指向地址的值是否相應改變了。 
  34.     */ 
  35.     memcpy(pbFile1, STR, strlen(STR)); 
  36.     printf("%s\n", pbFile1); 
  37.     printf("%s\n", pbFile2); 
  38.     //清理指針和內存 
  39.     UnmapViewOfFile(pbFile1); 
  40.     UnmapViewOfFile(pbFile2); 
  41.     CloseHandle(hFileMapping); 
  42.     CloseHandle(hFile); 
  43.     return 0; 
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章