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;