在Linux系统中,经常需要用到cp函数来实现对文件的拷贝,其原理无非就是将源文件打开,将其读到字节流中。
然后将字节流写到目标文件中去,在这里如果提前定义一个数组用来存放数据,定义小了无法将数据全部复制,定义大了浪费空间,于是此次我们采用动态申请的方式来灵活实现。
申请的大小可以采用lseek函数的返回值来确定堆空间申请多少合适,lseek函数原型如下
off_t lseek(int fd, off_t offset, int whence);
第一个参数fd为要进行偏移定位的文件描述符,
第二个参数offset为设置偏移量,负值为设置的偏移量的基础上向左偏移n个偏移量,正值为在设置偏移量的基础上向右偏移n个偏移量。
第三个参数有三个实参分别为
SEEK_SET
The file offset is set to offset bytes.
SEEK_CUR
The file offset is set to its current
location plus offset bytes.
SEEK_END
The file offset is set to the size of the file
plus offset bytes.
SEEK_SET:将偏移定位到文件起始位置
SEEK_CUR:将偏移定位到当前位置,即原本偏移在哪保持不变
SEEK_END:将偏移定位到文件末位位置
这三个实参配和offset使用,切记偏移不要超过文件范围,大了小了都会出现意想不到的结果
讲了这么多已经把要表达的步骤说完了,接下来一起剖析下代码吧。
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
int main(int argc,char *argv[])
{
if(argc<3) perror("param invaild");//判断参数小于3个不合法
int ret;
int fdSrc,fdDes; //定义源文件、目标文件描述符
char *buf; //定义字符指针,指向读取到的内容
fdSrc = open(argv[1],O_RDWR); //以可读可写方式打开源文件
ret = lseek(fdSrc,0,SEEK_END); //用ret来获取文件大小
lseek(fdSrc,0,SEEK_SET); //获取后将光标放回首位置,因为要读取整个文件,要从首开始读
buf = (char *)malloc(sizeof(char)*ret); //该文件的大小为ret个字节,所以需申请ret个字节来读取文件内容
read(fdSrc,buf,sizeof(char)*ret);
fdDes = open(argv[2],O_RDWR|O_CREAT,0666); //判断文件不存在的话对其进行创建
write(fdDes,buf,sizeof(char)*ret); //将读取的文件写到目标文件中
close(fdSrc);
close(fdDes);
}
好了,这就是用动态创建方式对cp函数进行的复写代码。