首页 > 技术文章 > mmap内存映射复习

jojodru 2016-03-24 19:49 原文

c语言初学时,比较常见的一个习题就是实现cp。

使用c库实现的cp就不赘述了。

最近工作用到内存映射,就拿来练下手,复习一下mmap的用法。

很简单,将目标文件和源文件映射到内存,然后使用memcpy拷贝即可。

可以省去中间缓存的创建,代码页较为简单,拷贝速度也不错。

  1 #include <stdio.h>
  2 #include <string.h>
  3 #include <sys/types.h>
  4 #include <sys/stat.h>
  5 #include <unistd.h>
  6 #include <fcntl.h>
  7 #include <sys/mman.h>
  8 
  9 #define COFYMODE 0666
 10 
 11 int copy(const char* src, const char* dest)
 12 {
 13     int ret = -1;
 14     int in_fd = -1, out_fd = -1;
 15     size_t filesize;
 16     char nullbyte;
 17     void *source_addr = NULL;
 18     void *dest_addr = NULL;
 19 
 20     /* check args */
 21     if(src == NULL || dest == NULL){
 22         fprintf(stderr,"file path can not be null\n");
 23         return ret;
 24     }
 25 
 26     /* open files */
 27     if((in_fd=open(src, O_RDONLY))==-1) {
 28         fprintf(stderr, "Cannot open %s\n", src);
 29         return ret;
 30     }
 31 
 32 
 33 #if defined(i386) || defined(__x86_64) || defined(__x86_64__) || defined(i686)
 34     if((out_fd=open(dest, O_RDWR|O_CREAT|O_TRUNC,COFYMODE))==-1)
 35     {
 36         fprintf(stderr, "Cannot open %s\n", dest);
 37         ret = -1;
 38         goto cleanup;
 39     }
 40 #else
 41     if((out_fd=open(dest, O_WRONLY|O_CREAT|O_TRUNC,COFYMODE))==-1)
 42     {
 43         fprintf(stderr, "Cannot create %s\n", dest);
 44         ret = -1;
 45         goto cleanup;
 46     }
 47 #endif
 48 
 49    if((filesize=lseek(in_fd,0,SEEK_END))==-1)
 50    {
 51        fprintf(stderr, "Could not seek to end of file %s\n", src);
 52         ret = -1;
 53         goto cleanup;
 54    }
 55 
 56    if(filesize == 0)
 57    {
 58        ret = 0;
 59        goto cleanup;
 60    }
 61 
 62     lseek(out_fd,filesize-1,SEEK_SET);
 63     write(out_fd,&nullbyte,1);
 64 
 65     /* setup the memory maps */
 66     if((source_addr=mmap(NULL,filesize,PROT_READ,MAP_SHARED,in_fd,0))==(void *)-1)
 67     {
 68         fprintf(stderr, "Error mapping file %s\n", src);
 69         ret = -1;
 70         goto cleanup;
 71     }
 72 
 73 
 74     if((dest_addr=mmap(NULL,filesize,PROT_WRITE,MAP_SHARED,out_fd,0))==(void *)-1)
 75     {
 76         fprintf(stderr, "Error mapping file %s\n", dest);
 77         ret = -1;
 78         goto cleanup;
 79     }
 80 
 81     /* copy the input to output by doing a memcpy */
 82     memcpy(dest_addr,source_addr,filesize);
 83 
 84 cleanup:
 85     /*unmap the fiels */
 86     if(source_addr) munmap(source_addr,filesize);
 87     if(dest_addr) munmap(dest_addr,filesize);
 88 
 89     /* close the files */
 90     if(in_fd > 0)close(in_fd);
 91     if(out_fd > 0) close(out_fd);
 92 
 93     return ret;
 94 }
 95 
 96 int main(int argc, char* argv[])
 97 {
 98     if(argc < 3)
 99     {
100         fprintf(stderr, "useage: %s src_file dest_file", argv[0]);
101         return -1;
102     }
103 
104     return copy(argv[1], argv[2]);
105 }

 

推荐阅读