1、背景介绍
将文件1的内容复制到文件2和文件3中;对于文件2,每次复制把文件1内容添加到文件2尾(保留文件2原有内容);
对于文件3,每次复制用文件1内容覆盖文件3原有内容(不保留文件3原有内容)。
2、代码实现
// printf()函数、perror()函数所需的头文件。
#include <stdio.h>
// open()函数所需的头文件。
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
// close()函数所需的头文件。
#include <unistd.h>
// strcmp()函数和memset()函数的头文件。
#include <string.h>
// 至少有两个参数至main函数:argc和argv,
// 第一个是提供给main函数的参数个数,
// 第二个是参数的字符串数组的指针。
// argc: 整数,用来统计你运行程序时送给main函数的命令行参数的个数。本例中argc为4。
// argv[]: 指针数组,用来存放指向你的字符串参数的指针,每一个元素指向一个参数。
// argv[0] 指向程序运行的全路径名,本例中为./hello。
// argv[1] 指向在dos命令行中执行程序名后的第一个字符串,本例中为file1。
// argv[2] 指向执行程序名后的第二个字符串,本例中为file2。
// argv[3] 指向执行程序名后的第三个字符串,本例中为file3。
int main(int argc, char *argv[])
{
// 如果命令行参数的个数为4(即./hello、file1、file2、file3这4个参数),
// 并且执行程序名后的第一个字符串和第二个字符串不相等(即file1和file2不相等),
// 第二个字符串和第三个字符串不相等(即file2和file3不相等),则进行后续复制文件操作。
if((argc == 4) && (strcmp(argv[1], argv[2]) != 0) &&(strcmp(argv[1], argv[3]) != 0))
{
// 定义int类型的变量fd_src,fd_dest1,fd_dest2,ret,
// fd_src,fd_dest1,fd_dest2用来接收open()函数的返回值。
// ret用来接收read()函数的返回值。
// fd_src用来接收用open()函数打开file1的返回值。
// fd_dest1用来接收用open()函数打开file2的返回值。
// fd_dest2用来接收用open()函数打开file3的返回值。
int fd_src, fd_dest1,fd_dest2,ret;
// 以只读的方式打开执行程序名后第一个字符串所表示的文件(即file1)。
fd_src = open(argv[1], O_RDONLY);
// 如果返回值小于0,即表明打开文件失败。
if(fd_src < 0)
{
// perror(s)函数用来将上一个函数发生错误的原因输出到标准设备,
// 参数s所指的字符串会先打印出,后面再加上错误原因字符串。
perror("open argv[1]");
// 返回-1,结束程序。
return -1;
}
// 以只写并追加的方式【如果原来文件里面有内容,则这次写入会写在文件的最末尾】
// 打开执行程序名后第二个字符串所表示的文件(即file2)。
fd_dest1 = open(argv[2], O_WRONLY|O_APPEND);
// 如果返回值小于0,则表明打开文件失败。
if(fd_dest1 < 0)
{
// 关闭执行程序名后第一个字符串所表示的文件(即file1)。
close(fd_src);
// perror(s)函数用来将上一个函数发生错误的原因输出到标准设备,
// 参数s所指的字符串会先打印出,后面再加上错误原因字符串。
perror("open argv[2]");
// 返回-1,结束程序。
return -1;
}
// 以只写并创建的方式打开执行程序名后第三个字符串所表示的文件(即file3)。
// 如果原来这个文件存在则会重新创建这个文件,原来的内容会被消除掉。
//(有点类似于先删除原来的文件再创建一个新的)
// 0644表示设置文件访问权限的初始值,0644应该是rw-r--r--,
// 即用户:可读可写、用户组: 可读、其他:可读。
fd_dest2 = open(argv[3], O_WRONLY|O_CREAT, 0644);
// 如果返回值小于0,则表明打开文件失败。
if(fd_dest2 < 0)
{
// 关闭执行程序名后第一个字符串所表示的文件(即file1)。
close(fd_src);
// perror(s)函数用来将上一个函数发生错误的原因输出到标准设备,
// 参数s所指的字符串会先打印出,后面再加上错误原因字符串。
perror("open argv[3]");
// 返回-1,结束程序。
return -1;
}
// 定义一个大小为1024个字节的字符数组,命名为buf。
char buf[1024] ="";
// 用do-while循环进行文件的复制操作。
do
{
// memset()函数把buf中所有字节都换作字符“0”,即对字符数组进行初始化操作。
memset(buf,0,sizeof(buf));
// read()函数会从fd_src所指的文件中传送大小为sizeof(buf)个字节的数据
//给buf指针所指的内存中。
// read()函数的返回值为实际读取到的字节数。
// 如果返回0, 表示已到达文件尾或是无可读取的数据。
ret = read(fd_src, buf, sizeof(buf));
// 如果read()函数实际读取到的字节数大于0,
// 则用write()函数把buf所指的内存写ret个字节到fd_dest1和fd_dest2所指的文件内。
if(ret>0){
printf("开始执行将文件file1的内容复制到文件file2的末尾!\n");
write(fd_dest1, buf, ret);
printf("将文件file1的内容复制到文件file2的末尾操作成功!\n");
printf("*********************************************\n");
printf("开始执行将文件file1的内容覆盖文件file3!\n");
write(fd_dest2, buf, ret);
printf("将文件file1的内容覆盖文件file3的内容操作成功!\n");
}
}while(ret >0);
//close()函数关闭file1。
close(fd_src);
//close()函数关闭file2。
close(fd_dest1);
//close()函数关闭file3。
close(fd_dest2);
}
// 程序结束。
return 0;
}