天刀追逐秦妙手:编写自己的“ cp ”指令(支持空洞文件)

来源:百度文库 编辑:中财网 时间:2024/05/06 07:44:42
编写自己的“ cp ”指令(支持空洞文件)2010-05-05 22:13

        我们知道 Shell 里面的指令功能很强大很出色。要自己编写函数完全模拟它的功能是很困难也很麻烦的。不过做为学习没必要跟他弄得一摸一样,能学到东西才是重点。这次编写了一个 copy 功能的函数。基本实现了 Shell 里面 cp 的功能。一般文件拷贝不成问题, 而且还支持空洞文件的拷贝,效率跟 cp 差不多。不过也有不完善的地方。

下面先演示一下功能

     空洞文件拷贝

[root@oraserver test2]# ll                       查看原文件
总计 24
-rw-r--r-- 1 root root 10000006 05-05 18:02 dst


[root@oraserver test2]# ./mycp dst cp01     开始拷贝,用法跟 cp 一样

                                             执行文件名+源文件+目标文件
[root@oraserver test2]# ll
总计 36
-rw-r--r-- 1 root root 10000006 05-05 20:38 cp01
-rw-r--r-- 1 root root 10000006 05-05 18:02 dst

root@oraserver test2]# diff dst cp01            文件比较——无错
[root@oraserver test2]# du -h dst cp01       查看文件大小 一样
12K     dst
12K     cp01
[root@oraserver test2]# od -c dst                查看空洞内容 一样
0000000 \0 \0 \0 \0 \0 \0 \0 \0 \0 \0 \0 \0 \0 \0 \0 \0
*
46113200   h   e   l   l   o \n
46113206
[root@oraserver test2]# od -c cp01
0000000 \0 \0 \0 \0 \0 \0 \0 \0 \0 \0 \0 \0 \0 \0 \0 \0
*
46113200   h   e   l   l   o \n
46113206


功能实现成功,普通文件拷贝也一样,不再演示

函数:

#include #include #include #include #include #define SIZE   4096  //  块大小为单位(效率最高)int main(int argc, char *argv[]){    int src, dst;    char buffer[SIZE];    char zero[SIZE] = { 0 };    int ret, len;    if (argc < 3)  //  判断参数    {        fprintf(stderr, "Usage: %s srcfile dstfile\n",                argv[0]);        return -1;    }    src = open(argv[1], O_RDONLY);    //  打开要复制的源文件    dst = open(argv[2], O_WRONLY | O_TRUNC | O_CREAT, 0644); //  创建生成的新文件    while (1)    {        if ((ret = read(src, buffer, SIZE)) == 0)  //  以块大小读取        {            break;      //  文件尾,退出        }        if (memcmp(buffer, zero, ret) == 0)   //  块大小为单位进行内存比较        {            lseek(dst, ret, SEEK_CUR);    //  全是空洞,偏移指针        }        else        {            write(dst, buffer, ret);    //  不全是空同写文件        }    }    len = lseek(dst, 0, SEEK_CUR);  //  获取总偏移量    ftruncate(dst, len);   //  设置文件大小,以防全是空洞    close(src);     //  关闭文件    close(dst);    return 0;}