天刀追逐秦妙手:编写自己的“ cp ”指令(支持空洞文件)
来源:百度文库 编辑:中财网 时间:2024/05/06 07:44:42
我们知道 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;}