linux下写一个简单的函数实现cp命令,能够复制普通文件,在线等,必采纳

linux下写一个简单的函数实现cp命令,能够复制普通文件,在线等,必采纳,第1张

#include<stdio.h>

#include<unistd.h>

#include<sys/stat.h>

#include<sys/types.h>

#include<fcntl.h>

int main(int argc,char **argv)

{

if(argc<3)//参数少于3,给出提示并退出

{

printf("请按如下格式运行!\n")

printf("./程序 源文件 目标文件\n")

return 0

}

int fd1 = open(argv[1],O_RDONLY)//只读方式打开源文件

if(-1 == fd1)

{

perror("打开文件失败")

return 0

}

int fd2 = open(argv[2],O_RDWR|O_CREAT|O_TRUNC,0666)//读写方式打开文件,有则清空,没有则创建

char buf[100]={0}

int res

while(res = read(fd1,buf,sizeof(buf)))//从源文件读出

{

write(fd2,buf,res)//写入到目标文件

}

close(fd1)//关闭文件

close(fd2)

return 0

}

该命令的功能是将给出的文件或目录拷贝到另一文件或目录中,同MSDOS下的copy命令一样,功能十分强大。

语法: cp [选项] 源文件或目录 目标文件或目录

说明:该命令把指定的源文件复制到目标文件或把多个源文件复制到目标目录中。

该命令的各选项含义如下:

- a 该选项通常在拷贝目录时使用。它保留链接、文件属性,并递归地拷贝目录,其作用等于dpR选项的组合。

- d 拷贝时保留链接。

- f 删除已经存在的目标文件而不提示。

- i 和f选项相反,在覆盖目标文件之前将给出提示要求用户确认。回答y时目标文件将被覆盖,是交互式拷贝。

- p 此时cp除复制源文件的内容外,还将把其修改时间和访问权限也复制到新文件中。

- r 若给出的源文件是一目录文件,此时cp将递归复制该目录下所有的子目录和文件。此时目标文件必须为一个目录名。

- l 不作拷贝,只是链接文件。

需要说明的是,为防止用户在不经意的情况下用cp命令破坏另一个文件,如用户指定的目标文件名已存在,用cp命令拷贝文件后,这个文件就会被新源文件覆盖,因此,建议用户在使用cp命令拷贝文件时,最好使用i选项。

例子:

Cp -i file1 file2               (将文档 file1 复制成 file2 . –i为提示确认。)

cp file1 dir1               将文档 file1 复制到目录 dir1 下,文件名仍为 file1.

cp /tmp/file1 .               将目录 /tmp 下的文档 file1复制到现行目录下,档名仍为 file1.

cp /tmp/file1 file2               将目录 /tmp 下的文档 file1现行目录下,档名为file2

cp -r dir1 dir2               (recursive copy) 复制整个目录.若目录 dir2 不存在,则将目录dir1,及其所有文档和子目录,复制到目录 dir2 下,新目录名称为dir1.若目录dir2不存在,则将dir1,及其所有文档和子目录,复制为目录 dir2.

CP,Content Provider,即内容提供商, 指依法或依约定拥有版权和/或邻接权以及与版权作品有关的其他权利的,以及依法或依约定有权代表版权人和/或邻接权人进行许可授权、收取版权使用费用的公司实体或机构。

CP,同样也是COUPLE的缩写,即配对,主要用在同人作品中.

比如,在火影忍者耽美同人里说CP是鼬卡或鼬X卡卡西,就是以宇智波鼬和旗木卡卡西为配对进行创作.

在化学领域,CP是指化学纯,标签为中蓝,用于一般化学试验。

CP,C代表电荷共轭的变换,是粒子和反粒子互相对称,即对于粒子和反粒子;P代表宇称变换,是空间反射对称,即同一种粒子之间互为镜像。

1,首先需要了解cp的原理。

2,可以参考cp的源码去了解其原理

3,cp命令的源码可以在linux内核中找到。

4,或者下载busybox其中也会有cp的源码

只有了解其原理之后才能谈如何实现。参考代码如下:

#include <stdio.h>

#include <stdlib.h>

#include <sys/stat.h>

#include <sys/types.h>

#include <fcntl.h>

#include <errno.h>

#include <unistd.h>

#include <string.h>

#define BUF_SIZE 1024

#define PATH_LEN 128

void my_err(char *err_string, int line )

{

    fprintf(stderr,"line:%d ",line)

    perror(err_string) 

    exit(1)

}

void copy_data(const int frd,const int fwd)

{

    int read_len = 0, write_len = 0

    unsigned char buf[BUF_SIZE], *p_buf

    while ( (read_len = read(frd,buf,BUF_SIZE)) ) {

        

        if (-1 == read_len) {

            my_err("Read error", __LINE__)

        }

        else if (read_len > 0) { //把读取部分写入目标文件

            p_buf = buf

            while ( (write_len = write(fwd,p_buf,read_len)) ) {

                if(write_len == read_len) {

                    break

                }

                else if (write_len > 0) { //只写入部分

                    p_buf += write_len

                    read_len -= write_len

                }

                else if(-1 == write_len) {

                    my_err("Write error", __LINE__)

                }

            }

            if (-1 == write_len) break

        }

    }

}

int main(int argc, char **argv) 

{

    

    int frd, fwd //读写文件描述符

    int len = 0

    char *pSrc, *pDes //分别指向源文件路径和目标文件路径

    struct stat src_st,des_st

    

    if (argc < 3) {

        printf("用法 ./MyCp <源文件路径> <目标文件路径>\n")

        my_err("arguments error ", __LINE__)

    }

    

    frd = open(argv[1],O_RDONLY)

    if (frd == -1) {

        my_err("Can not opne file", __LINE__)

    }

    if (fstat(frd,&src_st) == -1) {

        my_err("stat error",__LINE__)

    }

    /*检查源文件路径是否是目录*/

    if (S_ISDIR(src_st.st_mode)) {

        my_err("略过目录",__LINE__)

    }

    

    pDes = argv[2]

    stat(argv[2],&des_st)

    if (S_ISDIR(des_st.st_mode)) { //目标路径是目录,则使用源文件的文件名

        

        len = strlen(argv[1])

        pSrc = argv[1] + (len-1) //指向最后一个字符

        /*先找出源文件的文件名*/

        while (pSrc >= argv[1] && *pSrc != '/') {

            pSrc--

        }

        pSrc++//指向源文件名

        

        len = strlen(argv[2]) 

        // . 表示复制到当前工作目录

        if (1 == len && '.' == *(argv[2])) {

            len = 0 //没有申请空间,后面就不用释放

            pDes = pSrc

        }

        else { //复制到某目录下,使用源文件名

            pDes = (char *)malloc(sizeof(char)*PATH_LEN)

            if (NULL == pDes) {

                my_err("malloc error ", __LINE__)

            }

            

            strcpy(pDes,argv[2])

        

            if ( *(pDes+(len-1)) != '/' ) { //目录缺少最后的'/',则补上’/‘

                strcat(pDes,"/")

            }

            strcat(pDes+len,pSrc)

        }

    }

    

    /* 打开目标文件, 使权限与源文件相同*/ 

    fwd = open(pDes,O_WRONLY | O_CREAT | O_TRUNC,src_st.st_mode)

    if (fwd == -1) {

        my_err("Can not creat file", __LINE__)

    }

    copy_data(frd,fwd)

    //puts("end of copy")

    if (len > 0 && pDes != NULL)

        free(pDes)

    

    close(frd)

    close(fwd)

    return 0

}


欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/yw/7334574.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2023-04-04
下一篇 2023-04-04

发表评论

登录后才能评论

评论列表(0条)

保存