博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Linux 命令 "cp" 代码实现简介
阅读量:5942 次
发布时间:2019-06-19

本文共 6826 字,大约阅读时间需要 22 分钟。

本blog主要是模仿Linux的cp命令的功能,未实现参数,只是基础功能部分。

本文的主要目的在于练习 和 中的函数的使用。

主要功能包括两种:

  • 源文件属性为文件,拷贝到其它文件(内容复制)或目录(作为目录子文件)
  • 源文件属性为目录,拷贝到其它目录(作为子目录存在)

其实现的流程图如下所示:

mark

本copy我们通过三个文件来实现:

  • main.c:流程的实现
  • copy.c:拷贝功能的实现
  • copy.h:必要的头文件
  1. main.c

    /**********************************************************   File name:*   Description:*   Author: Jimmy_Nie*   Version     Modify      Time        *   v1.0        creat       2017-09-12**********************************************************/#include "copy_file.h"int main(int argc, char *argv[]){    //Check the arguments    if( 3 != argc)    {        printf("%s(%d): arguments error!\n",__FILE__, __LINE__);        exit(EXIT_FAILURE);    }    //check the source file is a file or a directory    struct stat src_stat;    //destination file check    struct stat dest_stat;    //If source is a file    if( FILES == check_file(argv[1], &src_stat) )    {        FILE_ENUM dest_enum;        dest_enum = check_file( argv[2], &dest_stat );        char cmd[100] = "";        char ch;        switch(dest_enum)        {            case NOT_EXIST:                sprintf(cmd, "touch %s", argv[2]);                system( cmd );                check_file( argv[2], &dest_stat );                cp_file(argv[1], argv[2], &dest_stat);                break;            case DIRECTORY:                cp_file(argv[1], argv[2], &dest_stat);                break;            case FILES:                fprintf(stdout, "Overwrite the dest file %s, [y/n]\n", argv[2]);                ch = getchar();                if( ch == 'Y' || ch == 'y' )                {                    cp_file(argv[1], argv[2], &dest_stat);                }                else                    exit(0);                break;            default:                fprintf(stderr, "%s(%d): file type error\n", __FILE__, __LINE__);        }    }    //If source file is a directory    else if( DIRECTORY == check_file(argv[1], &dest_stat) )    {        FILE_ENUM dest_enum;        dest_enum = check_file( argv[2], &dest_stat );        char cmd[100] = "";        switch(dest_enum)        {            case NOT_EXIST:                sprintf(cmd, "mkdir -p %s", argv[2]);                system( cmd );                cp_dir(argv[1], argv[2] );                break;            case DIRECTORY:                cp_dir(argv[1], argv[2]);                 break;            case FILES:                fprintf(stderr, "Can't copy a directory to a file\n");                exit(EXIT_FAILURE);                break;            default:                fprintf(stderr, "%s(%d): file type error\n", __FILE__, __LINE__);                break;        }    }    return 0;}
  2. copy.c

    #include "copy_file.h"FILE_ENUM check_file(char *var, struct stat *st){    if( stat(var, st) )    //if stat function error(renturn nonzero)    {        if( ENOENT == errno)    //No such file or directory        {            return NOT_EXIST;        }        else        {            perror("stat");            exit(EXIT_FAILURE);        }    }    else    // stat() ok, no error    {        //check file attr(dir or file)        if( S_ISDIR(st->st_mode ))              return DIRECTORY;        else if( S_ISREG(st->st_mode) )            return FILES;        else        {            fprintf(stderr, "%s(%d):file type error", __FILE__ , __LINE__);            exit(EXIT_FAILURE);        }    }}//-----------------------------------------------------int cp_file(char *src_var, char *dest_var, struct stat *st){    FILE *src = NULL;    FILE *dest = NULL;    if( S_ISREG(st->st_mode) )  //if dest is file    {        //1. open src and dest file        if( NULL == (src = fopen(src_var, "r")) )        {            perror("fopen");            exit(EXIT_FAILURE);        }        if( NULL == (dest = fopen(dest_var, "w+")) )        {            perror("fopen");            exit(EXIT_FAILURE);        }        //2. copy the context from src to dest        char buf[1024];        int num;        while(1)        {            // if at the end of file or an error occured            if( 1024 != (num = fread(buf, 1,1024, src)))            {                if( !feof(src))                {                    perror("fread");                    exit(EXIT_FAILURE);                }                else                {                    fwrite(buf, 1, num, dest);                    fclose(dest);   //3. close dest file                    break;                }            }            fwrite(buf, 1, 1024, dest);        }        //3. close src file        fclose(src);        return 0;    }    if( S_ISDIR(st->st_mode) )    {        char buf[100]="";        //make the relative path to absolute path        strncpy(buf, dest_var, sizeof(dest_var));        strcat(buf, src_var);        //if dest file doesn't exist, creat it first        char cmd[100]="";        sprintf(cmd, "touch %s",buf);        system(cmd);        struct stat new_dest_stat;        if( stat(buf, &new_dest_stat))        {            perror("stat");            exit(EXIT_FAILURE);        }        cp_file(src_var, buf, &new_dest_stat);    }    return 0;}//----------------------------------------------//if src file is a dirint cp_dir(char *src, char *dest){    DIR *dirp = NULL;    //1. open the dir    if( NULL == (dirp = opendir(src)) )    {        perror("opendir");        exit(EXIT_FAILURE);    }    struct dirent *entp = NULL;    //2. read the dir    while( NULL != (entp = readdir(dirp)))      //read the dir context    {        if( 0 == (strcmp(entp->d_name,"..")) || 0 == (strcmp(entp->d_name, ".")))        {            continue;        }        char src_buf[100] = "";        char dest_buf[100] = "";        sprintf(src_buf, "%s/%s\0", src, entp->d_name);        sprintf(dest_buf, "%s/%s\0", dest, entp->d_name);         struct stat src_stat;        if( stat(src_buf,&src_stat) )        {            perror("stat");            exit(EXIT_FAILURE);        }        if( S_ISREG(src_stat.st_mode) )        {            cp_file(src_buf, dest_buf, &src_stat);        }        else if( S_ISDIR(src_stat.st_mode) )        {            if( -1 == mkdir(dest_buf, src_stat.st_mode) )            {                perror("mkdir");                exit(EXIT_FAILURE);            }            cp_dir(src_buf, dest_buf);  //if subdir, recursive call itself        }    }    return 0;}
  3. copy.h

    #ifndef _COPY_H_#define _COPY_H_#include 
    #include
    #include
    #include
    #include
    #include
    #include
    #include
    typedef enum{ NOT_EXIST=1, DIRECTORY, FILES}FILE_ENUM;extern FILE_ENUM check_file(char *var, struct stat *st); //检查文件类型extern int cp_file(char *src_var, char *dest_var, struct stat *st); //copy文件extern int cp_dir(char *src, char *dest); //copy目录#endif

转载于:https://www.cnblogs.com/Jimmy1988/p/7509932.html

你可能感兴趣的文章
ASM概述
查看>>
【290】Python 函数
查看>>
godaddy域名转发(域名跳转)设置教程
查看>>
silverlight学习布局之:布局stackpanel
查看>>
理解并自定义HttpHandler
查看>>
从前后端分离到GraphQL,携程如何用Node实现?\n
查看>>
JavaScript标准库系列——RegExp对象(三)
查看>>
Linux Namespace系列(09):利用Namespace创建一个简单可用的容器
查看>>
关于缓存命中率的几个关键问题!
查看>>
oracle中create table with as和insert into with as语句
查看>>
kafka连接异常
查看>>
11g废弃的Hint - BYPASS_UJVC
查看>>
为什么工业控制系统需要安全防护?
查看>>
Mongodb部署记录[3]-主从搭建
查看>>
hive sql操作
查看>>
tomcat 深度优化
查看>>
127 - "Accordian" Patience
查看>>
Mac 常用快捷键
查看>>
阿里云CentOS7安装Oracle11GR2
查看>>
nginc+memcache
查看>>