zoukankan      html  css  js  c++  java
  • mmap内存映射复习

    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
    ");
     23         return ret;
     24     }
     25 
     26     /* open files */
     27     if((in_fd=open(src, O_RDONLY))==-1) {
     28         fprintf(stderr, "Cannot open %s
    ", 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
    ", 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
    ", 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
    ", 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
    ", 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
    ", 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 }
  • 相关阅读:
    mysql DATE_FORMAT FROM_UNIXTIME 的区别
    thinkphp按日期(天)统计数据
    ThinkPHP5 (mySQL) 统计各个时间段内的订单量
    转:mysql按时间统计数据,没有数据的时候自动补充0
    SQL的各种连接Join详解
    查询近7天,近1个月,近3个月每天的数据量,查询近一年每个月的数据量
    MySQL 如何生成日期表
    MySQL 生成日期表
    linux达人养成计划学习笔记(一)——命令基本格式及文件处理命令
    rviz学习笔记(二)——Markers: Points and Lines (C++) 点和线
  • 原文地址:https://www.cnblogs.com/jojodru/p/5316901.html
Copyright © 2011-2022 走看看