温馨提示×

温馨提示×

您好,登录后才能下订单哦!

密码登录×
登录注册×
其他方式登录
点击 登录注册 即表示同意《亿速云用户服务条款》

mmap中怎么实现文件拷贝功能

发布时间:2021-08-06 17:10:23 来源:亿速云 阅读:182 作者:Leah 栏目:编程语言

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()介入。

看完上述内容是否对您有帮助呢?如果还想对相关知识有进一步的了解或阅读更多相关文章,请关注亿速云行业资讯频道,感谢您对亿速云的支持。

向AI问一下细节

免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。

AI