#include <stdio.h>
#include <sys/types.h>
#include <dirent.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/stat.h>
#include <sys/mman.h>
#include <fcntl.h>
//cp <源文件> <目标文件>
int main(int argc,char **argv)
{
if(argc!=3)
{
printf(&quot;参数格式:./app <源文件> <目标文件>\n&quot;);
return 0;
}
int s_fd;
int o_fd;
struct stat s_buff;
char *mem_p;
/*1. 打开源文件*/
s_fd=open(argv[1],O_RDWR);
if(s_fd<0)
{
printf(&quot;打开源文件失败.\n&quot;);
exit(0);
}
/*2. 创建目标文件*/
o_fd=open(argv[2],O_RDWR|O_CREAT,S_IWUSR|S_IRUSR);
if(o_fd<0)
{
printf(&quot;创建目标文件失败.\n&quot;);
exit(0);
}
/*3. 获取源文件状态*/
stat(argv[1],&s_buff);
printf(&quot;源文件大小:%d Byte\n&quot;,s_buff.st_size);
/*4. 设置目标文件的大小*/
ftruncate(o_fd,s_buff.st_size);
/*5. 映射目标文件到内存*/
mem_p=mmap(NULL,s_buff.st_size,
PROT_READ|PROT_WRITE,MAP_SHARED,o_fd,0);
if(mem_p==NULL)
{
printf(&quot;空间映射失败.\n&quot;);
exit(0);
}
/*6. 计算每个进程拷贝多少字节*/
int cp_byte=s_buff.st_size/4; //每个子进程拷贝的字节数量
int m_byte=s_buff.st_size%4; //父进程拷贝剩余的字节数量
printf(&quot;cp_byte=%d*4,m_byte=%d\n&quot;,cp_byte,m_byte);
/*7. 创建子进程*/
int i;
pid_t pid;
int cnt;
for(i=0;i<4;i++)
{
pid=fork();
if(pid==0)break;//如果是子进程就退出
if(pid<0)
{
while(1)
{
if(wait(NULL)<0)break;
}
printf(&quot;子进程创建失败!\n&quot;);
exit(0);
}
}
if(i<4) //子进程
{
//将源文件的数据直接读取到目标文件中(内存)
lseek(s_fd,i*cp_byte,SEEK_SET);
cnt=read(s_fd,mem_p+i*cp_byte,cp_byte);
printf(&quot;子进程:%d,成功拷贝%d Byte\n&quot;,getpid(),cnt);
munmap(mem_p,s_buff.st_size);
close(s_fd);
close(o_fd);
}
else //父进程
{
//将源文件的数据直接读取到目标文件中(内存)
lseek(s_fd,i*cp_byte,SEEK_SET);
cnt=read(s_fd,mem_p+i*cp_byte,m_byte);
printf(&quot;父进程:%d,成功拷贝%d Byte\n&quot;,getpid(),cnt);
munmap(mem_p,s_buff.st_size);
close(s_fd);
close(o_fd);
//等待子进程退出
while(1)
{
if(wait(NULL)<0)break;
}
printf(&quot;文件拷贝成功. %s --> %s\n&quot;,argv[1],argv[2]);
}
return 0;
}
复制代码 |