1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
|
#include<stdio.h> #include<stdlib.h> #include<sys/mman.h> #include<unistd.h> #include<fcntl.h> #define
NumReconds 100 typedef struct { int iNum; char sName[24]; }
Recond; int main( void ) { Recond
recond,*mapped; int i,f; FILE *fp; fp= fopen ( "recond.dat" , "w+" ); for (
i=0; i < NumReconds; i++) { recond.iNum
= i; sprintf (recond.sName, "Recond-%d\n" ,i); fwrite (&recond, sizeof (Recond),1,fp); } fclose (fp); //使用傳統方式修改文件內容 fp
= fopen ( "recond.dat" , "r+" ); //獲得要修改文件的位置 fseek (fp,43* sizeof (recond),SEEK_SET); fread (&recond, sizeof (recond),1,fp); recond.iNum
= 143; sprintf (recond.sName, "Recond-%d" ,recond.iNum); fwrite (&recond, sizeof (recond),1,fp); fclose (fp); //使用內存映射的方式打開文件,修改文件內存 //注意這裏是open打開不是fopen!!!! f
= open( "recond.dat" ,O_RDWR); //獲得磁盤文件的內存映射 mapped
= (Recond *) mmap(0 , NumReconds * sizeof (Recond)
, PROT_READ|PROT_WRITE, MAP_SHARED, f, 0); mapped[43].iNum
= 999; sprintf (mapped[43].sName, "Recond-%d" ,mapped[43].iNum); //將修改同步到磁盤中 msync(( void *)mapped,NumReconds* sizeof (recond),MS_ASYNC); //關閉內存映射 munmap(( void *)mapped,NumReconds* sizeof (recond)); close(f); exit (0); } |
Linux C++內存映射方式讀寫文件
void *mmap(void *start, size_t length, int prot, int flags,
start:映射區的開始地址,設置爲0時表示由系統決定映射區的起始地址。
length:映射區的長度。//長度單位是 以字節爲單位,不足一內存頁按一內存頁處理
prot:期望的內存保護標誌,不能與文件的打開模式衝突。是以下的某個值,可以通過or運算合理地組合在一起
PROT_EXEC //頁內容可以被執行
PROT_READ //頁內容可以被讀取
PROT_WRITE //頁可以被寫入
PROT_NONE //頁不可訪問
MAP_FIXED //使用指定的映射起始地址,如果由start和len參數指定的內存區重疊於現存 映射空間,重疊部分將會被丟棄。如果指定的起始地址不可用,操作將會失敗。並且起始地 址必須落在頁的邊界上。
MAP_SHARED //與其它所有映射這個對象的進程共享映射空間。對共享區的寫入,相當於輸出到文件。直到msync()或者munmap()被調用,文件實際上不會被更新。
MAP_PRIVATE //建立一個寫入時拷貝的私有映射。內存區域的寫入不會影響到原文件。這個標誌和以上標誌是互斥的,只能使用其中一個。
MAP_DENYWRITE //這個標誌被忽略。
fd:有效的文件描述詞。一般是由open()函數返回,其值也可以設置爲-1,此時需要指定flags參數中的MAP_ANON,表明進行的是匿名映射。
進程在映射空間的對共享內容的改變並不直接寫回到磁盤文件中,往往在調用munmap()後才執行該操作。
flags:刷新的參數設置,可以取值MS_ASYNC/ MS_SYNC/ MS_INVALIDATE
其中:
取值爲MS_ASYNC(異步)時,調用會立即返回,不等到更新的完成;
取值爲MS_SYNC(同步)時,調用會等到更新完成之後返回;
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.