您好,登錄后才能下訂單哦!
mmap中怎么實現文件拷貝功能,很多新手對此不是很清楚,為了幫助大家解決這個難題,下面小編將為大家詳細講解,有這方面需求的人可以來學習下,希望你能有所收獲。
具體內容如下
/* * gcc -Wall -O3 -o copy_mmap copy_mmap.c */ #include < stdio.h > #include < stdlib.h > #include < string .h > /* for memcpy */ #include < strings.h > #include < sys / mman.h > #include < sys / types.h > #include < sys / stat.h > #include < fcntl.h > #include < unistd.h > #define PERMS 0600 int main ( int argc, char * argv[] ){ int src, dst; void * sm, * dm; struct stat statbuf; if ( argc != 3 ) { fprintf( stderr, " Usage: %s \n " , argv[ 0 ] ); exit( EXIT_FAILURE ); } if ( ( src = open( argv[ 1 ], O_RDONLY ) ) < 0 ) { perror( " open source " ); exit( EXIT_FAILURE ); } /* 為了完成復制,必須包含讀打開,否則mmap()失敗 */ if ( ( dst = open( argv[ 2 ], O_RDWR | O_CREAT | O_TRUNC, PERMS ) ) < 0 ) { perror( " open target " ); exit( EXIT_FAILURE ); } if ( fstat( src, & statbuf ) < 0 ) { perror( " fstat source " ); exit( EXIT_FAILURE ); } /* * 參看前面man手冊中的說明,mmap()不能用于擴展文件長度。所以這里必須事 * 先擴大目標文件長度,準備一個空架子等待復制。 */ if ( lseek( dst, statbuf.st_size - 1 , SEEK_SET ) < 0 ) { perror( " lseek target " ); exit( EXIT_FAILURE ); } if ( write( dst, & statbuf, 1 ) != 1 ) { perror( " write target " ); exit( EXIT_FAILURE ); } /* 讀的時候指定 MAP_PRIVATE 即可 */ sm = mmap( 0 , ( size_t )statbuf.st_size, PROT_READ, MAP_PRIVATE | MAP_NORESERVE, src, 0 ); if ( MAP_FAILED == sm ) { perror( " mmap source " ); exit( EXIT_FAILURE ); } /* 這里必須指定 MAP_SHARED 才可能真正改變靜態文件 */ dm = mmap( 0 , ( size_t )statbuf.st_size, PROT_WRITE, MAP_SHARED, dst, 0 ); if ( MAP_FAILED == dm ) { perror( " mmap target " ); exit( EXIT_FAILURE ); } memcpy( dm, sm, ( size_t )statbuf.st_size ); /* * 可以不要這行代碼 * * msync( dm, ( size_t )statbuf.st_size, MS_SYNC ); */ return ( EXIT_SUCCESS );}
mmap()好處是處理大文件時速度明顯快于標準文件I/O,無論讀寫,都少了一次用戶空間與內核空間之間的復制過程。操作內存還便于設計、優化算法。
文件I/O操作/proc/self/mem不存在頁邊界對齊的問題,但至少Linux的mmap()的最后一個形參offset并未強制要求頁邊界對齊,如果提供的值未對齊,系統自動向上舍入到頁邊界上。malloc()分配得到的地址不見得對齊在頁邊界上。
/proc/self/mem和/dev/kmem不同。root用戶打開/dev/kmem就可以在用戶空間訪問到內核空間的數據,包括偏移0處的數據,系統提供了這樣的支持。顯然代碼段經過/proc/self/mem可寫映射后已經可寫,無須mprotect()介入。
看完上述內容是否對您有幫助呢?如果還想對相關知識有進一步的了解或閱讀更多相關文章,請關注億速云行業資訊頻道,感謝您對億速云的支持。
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。