1. 基于C语言实现,文件IO练习
2.代码实现
2.1(命令行指定)使用父子进程拷贝同一个文件,父进程拷贝前半部分,子进程拷贝后半部分
#include // Shift + Alt + F 实现代码的对齐;
#include
#include
//#include
#include
#include
#include
#include
//#include
//#include
int get_src_file_len(const char *srcfile,const char * destfile)
{
int sfd,dfd;
int len=0;
//打开目标要拷贝的文件
if((sfd = open(srcfile,O_RDONLY))==-1){//只读
printf("open srcfile error");
}
//打开存放拷贝的文件
if((dfd = open(destfile,O_RDWR|O_CREAT|O_TRUNC,0664))==-1){
//读写| 创建文件| 清空文件
printf("open destfile error");
}
//读取目标要拷贝的文件的字节数
len = lseek(sfd,0,SEEK_END);
close(sfd);//关闭文件
close(dfd);
return len;
}
int copy_file(const char *srcfile,const char * destfile,int start,int len)
{
int sfd,dfd;
char buf[10] = {0};
int ret=0;
//记录已经读取字节数
int i = 0;
//打开目标要拷贝的文件
if((sfd = open(srcfile,O_RDONLY))==-1){//只读
printf("open srcfile error");
}
//打开存放拷贝的文件
if((dfd = open(destfile,O_RDWR))==-1){//读写
printf("open destfile error");
}
//光标从头开始,移动start
lseek(sfd,start,SEEK_SET);
lseek(dfd,start,SEEK_SET);
while(1){
ret = read(sfd,buf,sizeof(buf));
i+=ret;//记录已经读取字节数
//结尾||读多了
if(ret==0 || i>len) {
write(dfd,buf,ret-(i-len));
break;
}
write(dfd,buf,ret);
}
close(sfd);
close(dfd);
return 0;
}
int main(int argc,const char * argv[])
{
//检测命令行 3个参数
if(argc != 3){
fprintf(stderr,"input error,try againn");
fprintf(stderr,"usage:./a.out srcfile,destfilen");
return -1;
}
int len = get_src_file_len(argv[1],argv[2]);
printf("len = %dn",len);
//新建子进程
pid_t pid;
pid = fork();
if(pid < 0){
printf("fork error");
}else if(pid == 0){
printf("child start = %d,len=%dn",0,len/2);
//进程写前半部分
copy_file(argv[1],argv[2],0,len/2);
exit(EXIT_SUCCESS);//退出进程的时候会刷新缓冲区
}else{
printf("parent start = %d,len=%dn",len/2,len-len/2);
//进程写后半部分
copy_file(argv[1],argv[2],len/2,(len-len/2));
wait(NULL);//阻塞等待回收子进程的资源
}
return 0;
}
执行结果
2.2(非命令行指定)使用父子进程拷贝同一个文件,父进程拷贝前半部分,子进程拷贝后半部分
#include // Shift + Alt + F 实现代码的对齐;
#include
#include
//#include
#include
#include
#include
//#include
//#include
int copy_2(int fd, int df)
{
int ret, ret0, ret1;
char buy[1];
//读取目标要拷贝的文件的字节数
ret1 = lseek(fd, 0, SEEK_END) / 2;
//记录已经读取字节数
int i = 0;
//进程写前半部分
// SEEK_END从结尾开始 ;lseek功能:修改文件中光标的位置,
//返回值:成功返回光标当前位置到开头的字节数
if ((ret0 = lseek(df, 0, SEEK_END)) <= 0) //还没有进程执行
{
lseek(fd, 0, SEEK_SET);
while ((ret = read(fd, buy, sizeof(buy))) > 0 && i < ret1)
{
write(df, buy, ret);
i += ret;
}
printf("前半部分n");
}
//进程写后半部分
else if ((ret0 = lseek(df, 0, SEEK_END)) > 0) //进程已经执行
{
// SEEK_SET从头开始
lseek(fd, ret0, SEEK_SET);
while ((ret = read(fd, buy, sizeof(buy))) > 0)
{
write(df, buy, ret);
}
printf("后半部分n");
}
return 0;
}
int main(int argc, char const *argv[])
{
int fd, df;
//先打开目标,要拷贝的文件
if ((fd = open("./01.txt", O_RDONLY)) == -1)
printf("open src errorn");
//打开拷贝存放的文件 //a+
if ((df = open("./03-03作业-存放拷贝.txt", O_RDWR | O_APPEND | O_CREAT, 0664)) == -1)
printf("open src errorn");
pid_t pid;
char s1[50] = {0};
//创建子进程
pid = fork(); // fork成功父进程收到子进程的PID,子进程收到0.
if (pid < 0)
{
printf("fork errorn");
}
else if (pid == 0)
{
printf("n");
printf("这是子进程n");
printf("n");
copy_2(fd, df);
}
else
{
printf("这是父进程n");
printf("n");
copy_2(fd, df);
wait(NULL); //阻塞等待回收子进程的资源
}
return 0;
}
执行结果
2.3 (命令行指定)使用三个进程拷贝同一个文件,每个进程拷贝文件的1/3
#include // Shift + Alt + F 实现代码的对齐;
#include
#include
//#include
#include
#include
#include
#include
//#include
//#include
int get_src_file_len(const char *srcfile,const char * destfile)
{
int sfd,dfd;
int len=0;
//打开目标要拷贝的文件
if((sfd = open(srcfile,O_RDONLY))==-1){//只读
printf("open srcfile error");
}
//打开存放拷贝的文件
if((dfd = open(destfile,O_RDWR|O_CREAT|O_TRUNC,0664))==-1){
//读写| 创建文件| 清空文件
printf("open destfile error");
}
//读取目标要拷贝的文件的字节数
len = lseek(sfd,0,SEEK_END);
close(sfd);//关闭文件
close(dfd);
return len;
}
int copy_file(const char *srcfile,const char * destfile,int start,int len)
{
int sfd,dfd;
char buf[10] = {0};
int ret=0;
//记录已经读取字节数
int i = 0;
//打开目标要拷贝的文件
if((sfd = open(srcfile,O_RDONLY))==-1){//只读
printf("open srcfile error");
}
//打开存放拷贝的文件
if((dfd = open(destfile,O_RDWR))==-1){//读写
printf("open destfile error");
}
//光标从头开始,移动start
lseek(sfd,start,SEEK_SET);
lseek(dfd,start,SEEK_SET);
while(1){
ret = read(sfd,buf,sizeof(buf));
i+=ret;//记录已经读取字节数
//结尾||读多了
if(ret==0 || i>len) {
write(dfd,buf,ret-(i-len));
break;
}
write(dfd,buf,ret);
}
close(sfd);
close(dfd);
return 0;
}
int main(int argc,const char * argv[])
{
//检测命令行 3个参数
if(argc != 3){
fprintf(stderr,"input error,try againn");
fprintf(stderr,"usage:./a.out srcfile,destfilen");
return -1;
}
int len= get_src_file_len(argv[1],argv[2]);
printf("len = %dn",len);
//新建子进程
pid_t pid,pid1;
pid = fork();
if(pid < 0){
printf("fork error");
}else if(pid == 0){
printf("child1 start = %d,len=%dn",0,len/3);
//进程写前1/3部分
copy_file(argv[1],argv[2],0,len/3);
exit(EXIT_SUCCESS);
}else{
//新建子进程
pid1=fork();
if(pid1<0){
printf("fork pid1 process error");
}else if(pid1 == 0){
printf("child2 start = %d,len=%dn",len/3,(len/3)*2);
//进程写中1/3部分
copy_file(argv[1],argv[2],len/3,(len/3)*2);
exit(EXIT_SUCCESS);
}
//进程写最后半部分
printf("parent start = %d,len=%dn",(len/3)*2,len-(len/3)*2);
copy_file(argv[1],argv[2],(len/3)*2,len-(len/3)*2);
wait(NULL); //阻塞回收子进程,但是回收那个子进程的资源不确定,只要回收一个就会退出
wait(NULL); //阻塞回收子进程,但是回收那个子进程的资源不确定,只要回收一个就会退出
}
return 0;
}
执行结果
2.4 (非命令行指定)使用三个进程拷贝同一个文件,每个进程拷贝文件的1/3
#include // Shift + Alt + F 实现代码的对齐;
#include
#include
//#include
#include
#include
#include
//#include
//#include
int copy_3(int fd, int df)
{
int ret, ret0, ret1;
char buy[1];
//读取目标要拷贝的文件的字节数
ret1 = lseek(fd, 0, SEEK_END) / 3;
//记录已经读取字节数
int i = 0;
//进程写前部分
// SEEK_END从结尾开始 ;lseek功能:修改文件中光标的位置,
//返回值:成功返回光标当前位置到开头的字节数
if ((ret0 = lseek(df, 0, SEEK_END)) <= 0) //还没有进程执行
{
lseek(fd, 0, SEEK_SET);
while ((ret = read(fd, buy, sizeof(buy))) > 0 && i < ret1)
{
write(df, buy, ret);
i += ret;
}
printf("前部分n");
}
//进程写中部分
else if ((ret0 = lseek(df, 0, SEEK_END))==ret1) //进程已经执行
{
// SEEK_SET从头开始
lseek(fd, ret0, SEEK_SET);
while ((ret = read(fd, buy, sizeof(buy))) > 0 && i < ret1)
{
write(df, buy, ret);
i += ret;
}
printf("中部分n");
}
//进程写后部分
else //进程已经执行
{
ret0 = lseek(df, 0, SEEK_END);
// SEEK_SET从头开始
lseek(fd, ret0, SEEK_SET);
while ((ret = read(fd, buy, sizeof(buy))) > 0)
{
write(df, buy, ret);
}
printf("后部分n");
}
return 0;
}
int main(int argc, char const *argv[])
{
int fd, df;
//先打开目标,要拷贝的文件
if ((fd = open("./01.txt", O_RDONLY)) == -1)
printf("open src errorn");
//打开拷贝存放的文件 //a+
if ((df = open("./04-04作业-存放3进程拷贝.txt", O_RDWR | O_APPEND | O_CREAT, 0664)) == -1)
printf("open src errorn");
pid_t pid;
char s1[50] = {0};
//创建子进程
pid = fork(); // fork成功父进程收到子进程的PID,子进程收到0.
if (pid < 0)
{
printf("fork errorn");
}
else if (pid == 0)
{
printf("n");
printf("这是子1进程n");
printf("n");
copy_3(fd, df);
}
else
{
//父进程再创建子进程
pid_t pid1;
pid1 = fork();
if (pid1 < 0)
{
printf("fork errorn");
}
else if (pid1 == 0)
{
printf("n");
printf("这是子2进程n");
printf("n");
copy_3(fd, df);
}
else
{
printf("这是父进程n");
printf("n");
copy_3(fd, df);
wait(NULL); //阻塞等待回收子进程的资源
wait(NULL); //阻塞等待回收子进程的资源
}
}
return 0;
}
执行结果
6. 非原创