linux系统下实现文件拷贝

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 5

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 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;

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值