linux系统下实现文件拷贝

来源:互联网 发布:城市大数据专业委员会 编辑:程序博客网 时间:2024/06/05 10:30

1,利用read, write实现文件拷贝

#include<stdio.h>#include<fcntl.h>#include<stdlib.h>#include<unistd.h>int main(int argc, char* argv[]){  if(argc < 3)  {    printf("input fail\n");    exit(-1);  }  int fd1 = open(argv[1], O_RDONLY);  if(fd1 == -1)  {    perror("open fail");    exit(1);  }  int fd2 = open(argv[2], O_CREAT | O_RDWR, 0664);  if(fd2 == -1)  {      perror("open fail");      exit(1);  }  char c;  int len = read(fd1, &c, sizeof(char));  while(len)  {    write(fd2, &c, len);    len = read(fd1, &c, sizeof(char));  }  close(fd1);  close(fd2);  return 0;}

2,利用mmap映射区实现拷贝,将源文件和目的文件都映射到共享映射区

#include<stdio.h>#include<fcntl.h>#include<stdlib.h>#include<unistd.h>#include<sys/mman.h>#include<sys/wait.h>#include<sys/stat.h>#include<string.h>int main(int argc, char* argv[]){  if(argc < 3)  {    printf("input fail\n");    exit(-1);  }  int src_fd = open(argv[1], O_RDONLY);//源文件  if(src_fd == -1)  {    perror("open fail");    exit(1);  }  struct stat statbuff;//获取源文件的大小  stat(argv[1], &statbuff);  int filesize = statbuff.st_size;  int dst_fd = open(argv[2], O_CREAT | O_RDWR, 0664);//目的文件  if(dst_fd == -1)  {    perror("open fail");    exit(1);  }  ftruncate(dst_fd, filesize);//目的文件大小等于源文件  void* src_mm;  char* dst_mm;  src_mm = mmap(NULL, filesize, PROT_READ, MAP_SHARED, src_fd, 0);//源文件映射  if(src_mm == MAP_FAILED)  {    perror("mmap1 fail");    exit(1);  }  dst_mm = mmap(NULL, filesize, PROT_READ | PROT_WRITE, MAP_SHARED, dst_fd, 0);//目的文件映射   if(dst_mm == MAP_FAILED)  {    perror("mmap2 fail");    exit(1);  }  memcpy(dst_mm, src_mm, filesize);//拷贝  munmap(dst_mm, filesize);//释放共享映射区  munmap(src_mm, filesize);  close(src_fd);  close(src_fd);  return 0;

3,利用多进程和mmap共享映射区实现拷贝

#include<stdio.h>#include<fcntl.h>#include<stdlib.h>#include<unistd.h>#include<sys/mman.h>#include<sys/wait.h>#include<sys/stat.h>#include<string.h>#define N 5int main(int argc, char* argv[]){  if(argc < 3)  {    printf("input fail\n");    exit(-1);  }  int src_fd = open(argv[1], O_RDONLY);  if(src_fd == -1)  {    perror("open fail");    exit(1);  }  struct stat statbuff;  stat(argv[1], &statbuff);  int filesize = statbuff.st_size;  int copyLen = filesize/N; //每个进程复制文件的大小  int lastCopyLen = filesize%copyLen+copyLen; //最后一个进程复制的文件大小,因为要复制到文件末尾  int dst_fd = open(argv[2], O_CREAT | O_RDWR, 0664);  if(dst_fd == -1)  {    perror("open fail");    exit(1);  }  ftruncate(dst_fd, filesize);  void* src_mm;  void* dst_mm;  src_mm = mmap(NULL, filesize, PROT_READ, MAP_SHARED, src_fd, 0);//源文件映射  if(src_mm == MAP_FAILED)  {    perror("mmap1 fail");    exit(1); }  dst_mm = mmap(NULL, filesize, PROT_READ | PROT_WRITE, MAP_SHARED, dst_fd, 0);//目的文件映射  if(dst_mm == MAP_FAILED)  {    perror("mmap2 fail");    exit(1);  }  int i;  pid_t pid;  for(i = 0;i < N;i++)//创建5个进程  {     pid = fork();     if(pid == 0)       break;     else if(pid == -1)     {       perror("create process fail");       exit(1);     }  }  if(i < N)//子进程复制  {    void* des_addr = dst_mm+i*copyLen;    void* src_addr = src_mm+i*copyLen;    if(i == N-1)//最后一个子进程      memcpy(des_addr, src_addr, lastCopyLen);    else//其他子进程      memcpy(des_addr, src_addr, copyLen);  }  else  {    pid_t p;    do    {      p = waitpid(-1, NULL, WNOHANG);      sleep(1);    }while(p==0 || p != -1);//父进程不阻塞轮询回收子进程    printf("waitpid finish\n");    munmap(dst_mm, filesize);//释放共享映射区    munmap(src_mm, filesize);    close(src_fd);//关闭文件    close(des_fd);  }  return 0;