zoukankan      html  css  js  c++  java
  • Linux 父子进程实现复制文件内容到另一个文件内

    1. 子进程先拷贝前一半 ,父进程一直阻塞到子进程拷贝完再拷贝后一半

    /* 子进程先拷贝前一半文件,父进程先阻塞等待子进程拷贝完前一半内容,
     * 然后父进程在拷贝,后一半内容
     * */
    #include <stdio.h>
    #include <stdlib.h>
    #include <unistd.h>
    #include <sys/types.h>
    #include <sys/stat.h>
    #include <fcntl.h>
    #include <sys/wait.h>
    
    //pid_t fork(void);
    int main(int argc, const char *argv[])
    {
        int fd_r, fd_w;
        char buf[5] = {0};
        int status;
        fd_r = open(argv[1],O_RDONLY); //打开读取内容的文件
        if(fd_r < 0)
        {    perror("read file  open fail : ");    return -1;    }
    
        fd_w = open(argv[2],O_WRONLY | O_APPEND,0666); //打开要写入的文件
        if(fd_w < 0)
        {    perror("write file  open fail : ");close(fd_r);    return -1;    }
    
        off_t fileSize = 0;//文件大小
        fileSize = lseek(fd_r,0,SEEK_END) - lseek(fd_r,0,SEEK_SET);//读取源文件有多少个字符:w
        printf("源文件大小:%ld
    ",fileSize);
        off_t c_read_size;//子进程,读取文件的大小
        c_read_size = fileSize / 2;
    
        off_t f_read_size;//父进程,读取文件的大小
        f_read_size = fileSize - c_read_size;
    
    
    #if 1
        pid_t pid ;
        pid = fork();
        if(pid == -1)  {perror("pid fail : ");    exit(1);}
    
        else if(pid == 0)//子进程
        {
            printf("子进程开始
    ");
            printf("子进程读取大小:%ld
    ",c_read_size);
    
            ssize_t size_cnt = 0;//记录读取的个数
            ssize_t temp_size = 0;//临时读取记录
            while(1) //循环读,读取到中间位置
            {
                temp_size = read(fd_r,buf,1);
                if(temp_size <= 0)//没有读取到数据,或者读取出错
                {
                    printf("child read fail or end
    ");
                    break;
                }
                ssize_t tt =0; //子进程写入失败
                tt = write(fd_w,buf,1); //读取到 数据写入文件
                if(tt ==-1)
                {    perror("child write file fail :");    break;    }
    
                size_cnt = size_cnt + temp_size;
                if(size_cnt >= c_read_size) //读取到该读的数据
                {
                    printf("child write file end 
    ");
                    break;
                }
            }
            exit(1); //退出子进程
        }
        else //父进程
        {
            waitpid(pid, &status, 0);//等待子进程执行完在执行
            printf("父进程开始
    ");
            printf("父进程读取大小:%ld
    ",f_read_size);
            lseek(fd_r,-f_read_size,SEEK_END);//相对文件末尾向移动到,子进程读取的位置
        
            while(1)//开始读取数据
            {
                ssize_t f_read_size;
                f_read_size = read(fd_r,buf,1);
                if(f_read_size <= 0)//读取到末尾返回值为 0 
                {
                    printf("father read file end
    ");
                    break;
                }
                ssize_t t =0; //父进程写入失败
                t = write(fd_w,buf,1);
                if(t ==-1)
                {
                    perror("father write file fail : ");
                    break;
                }
            }
            printf("father write file end 
    ");    
            exit(1);
        }
    #endif
        close(fd_r);
        close(fd_w);
        return 0;
    }

    测试:

         

    2. 父子进程同时拷贝,父进程拷贝前一半,子进程拷贝后一半,写文件的顺序不确定,所以写入后内容会乱

    /* copy文件,父进程先拷贝前一半,子进程拷贝后一半
     * 文件内容可以完整拷贝,写数据时顺序会打乱
     * 父进程写一点,子进程写一点
     * */
    #include <stdio.h>
    #include <unistd.h>
    #include <stdlib.h>
    #include <sys/types.h>
    #include <sys/stat.h>
    #include <fcntl.h>
    #include <sys/wait.h>
    
    int main(int argc, const char *argv[])
    {
        int fd_r,fd_w;
        off_t size;
        char ch = '';
        pid_t pid;
        char buf[64] = {0};
        ssize_t tmp = 0;
    
        if((fd_r = open(argv[1],O_RDONLY)) == -1)
        {
            perror("fcntlail to open fd_r");
            exit(1);
        }
    
        if((fd_w = open(argv[2],O_WRONLY|O_CREAT|O_TRUNC,0666)) == -1) //打开写的文件,没有就创建,有内容就清空,只写方式打开
        {
            close(fd_r);
            perror("fail to open FD_ZEROBASED_w");
            exit(1);
        }
    
        size = lseek(fd_r,0,SEEK_END);
        lseek(fd_w,size    - 1,SEEK_SET);
        write(fd_w,&ch,1);//在文件的末尾先添加一个 '' 结尾符,确定写文件的大小
    
        size /= 2;  //size = size / 2; //文件大小的一半
    
        pid = fork();
        if(pid < 0)
        {
            perror("fail to fork");
            exit(1);
        }
        else if(pid == 0) //子进程拷贝后一半
        {
            lseek(fd_r,size,SEEK_SET);
            lseek(fd_w,size,SEEK_SET);
    
            while((tmp = read(fd_r,buf,sizeof(buf))) > 0)
            {
                write(fd_w,buf,tmp);
            }
    
            close(fd_r);
            close(fd_w);
            exit(0);
        }
        else //父进程,拷贝前一半
        {
            lseek(fd_r,0,SEEK_SET);
            lseek(fd_w,0,SEEK_SET);
            while(1)
            {
                if(size > sizeof(buf))
                {
                    tmp = read(fd_r,buf,sizeof(buf));
                }
                else
                {
                    tmp = read(fd_r,buf,size);
                }
    
                if(tmp <= 0)
                {
                    break;
                }
                size -= tmp;//size = size - tmpfd_w;
    
                write(fd_w,buf,tmp);
            }
            wait(NULL);//等待回收子进程
            close(fd_r);
            close(fd_w);
        }
        return 0;
    }
  • 相关阅读:
    ERROR Function not available to this responsibility.Change responsibilities or contact your System Administrator.
    After Upgrade To Release 12.1.3 Users Receive "Function Not Available To This Responsibility" Error While Selecting Sub Menus Under Diagnostics (Doc ID 1200743.1)
    产品设计中先熟练使用铅笔 不要依赖Axure
    12.1.2: How to Modify and Enable The Configurable Home Page Delivered Via 12.1.2 (Doc ID 1061482.1)
    Reverting back to the R12.1.1 and R12.1.3 Homepage Layout
    常见Linux版本
    网口扫盲二:Mac与Phy组成原理的简单分析
    VMware 8安装苹果操作系统Mac OS X 10.7 Lion正式版
    VMware8安装MacOS 10.8
    回顾苹果操作系统Mac OS的发展历史
  • 原文地址:https://www.cnblogs.com/electronic/p/10932631.html
Copyright © 2011-2022 走看看