Bootstrap

根据共享内存实现copy(拷贝)---linux-c/c++

实例为将图片进行拷贝,在Linux系统下的运行程序如下:

setfile.c

#include <stdio.h>
#include <sys/ipc.h>
#include <sys/shm.h>
#include <string.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>

/* 根据要拷贝文件大小开辟共享内存大小 */

int main(int argc, const char *argv[]){
    if(argc != 2){
        printf("Usage: %s filename\n", argv[0]);return -1;
    }

    key_t key;
    int shmid;
    char *addr = NULL;
    if(-1 == (key=ftok("/home", 1))){
        perror("ftok");return -1;
    }

    //获取目标文件的大小--根据stat函数获取属性
    struct stat filebuf;
    if(-1 == stat(argv[1], &filebuf)){
        perror("stat");return -1;
    }
    printf("调整之前:file_size= %ld\n", filebuf.st_size);
    off_t file_size = filebuf.st_size;

    //将文件大小数值保存至指定文件中,以便于读进程能够访问同一ipc对象
    FILE *fp_size = fopen("/home/wang/project/1", "w+");
    fwrite(&file_size, 1, sizeof(file_size), fp_size);
    fclose(fp_size);
    
    //调整文件的大小为4096整数倍
    while(file_size % 4096 != 0){
        file_size++;
    }
    printf("调整之后:file_size= %ld\n", file_size);
    
    //创建共享内存
    if(-1 == (shmid = (shmget(key, file_size, IPC_CREAT|0666)))){
        perror("shmget");return -1;
    }

    //映射
    if((void *)-1 == (addr = shmat(shmid, NULL, 0))){
        perror("shmat");return -1;
    }

    //打开源文件
    FILE *fp = fopen(argv[1], "rb+");
    char *tmp = addr;        //临时指针
    int readlen = 0;
    
    //循环读取,将数据写入共享内存段,并且每次写入之后要偏移指针
    while((readlen =fread(tmp, 1, 4096, fp))){
        tmp += readlen;
    }
    fclose(fp);
    
    //取消映射
    shmdt(addr);
    return 0;
}

getfile.c

#include <stdio.h>
#include <sys/ipc.h>
#include <sys/shm.h>
#include <string.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>

/* 根据要拷贝文件大小开辟共享内存大小 */

int main(int argc, const char *argv[]){
    if(argc != 2){
        printf("Usage: %s filename", argv[0]);return -1;
    }

    key_t key;
    int shmid;
    char *addr = NULL;
    long file_size = 0;
    if(-1 == (key=ftok("/home", 1))){
        perror("ftok");return -1;
    }
    
    //从指定文件中获取文件大小,以便于读进程能够访问同一ipc对象
    FILE *fp_size = fopen("/home/wang/project/1", "rb+");
    fread(&file_size, 1, sizeof(file_size), fp_size);
    fclose(fp_size);
    printf("文件真实大小:%ld\n", file_size);
    
    int relsize = file_size;
    
    //调整文件的大小为4096整数倍
    while((file_size) % 4096 != 0){
        file_size++;
    }
    printf("调整之后:file_size= %ld\n", file_size);
    
    //创建共享内存
    if(-1 == (shmid = (shmget(key, file_size, IPC_CREAT|0666)))){
        perror("shmget");return -1;
    }

    //映射
    if((void *)-1 == (addr = shmat(shmid, NULL, 0))){
        perror("shmat");return -1;
    }

    //打开目标文件 [拷贝过后生成的文件]
    FILE *fp = fopen(argv[1], "w+");
    
    char *tmp = addr;        //临时指针
    int writelen = 0;
    //循环从共享内存段读取数据放入文件
    while( relsize ){

        if(relsize < 4096){
            writelen = fwrite(tmp, 1, relsize, fp);
            break;
        }
        writelen = fwrite(tmp, 1, 4096, fp);
        tmp += writelen;            //写入之后偏移共享内存段的指针
        relsize -= writelen;                //文件大小减少对应的字节数
    }
  
    fclose(fp);
    
    //取消映射
    shmdt(addr);
    shmctl(shmid, IPC_RMID, NULL);
    return 0;
}

;