文件IO操作–复制文件
- 要求:将文件1复制到文件2
- 流程:
通过命令行传递参数;
打开文件1,文件2 ;
读出文件1当中的数据,数据存在缓冲区中;
将缓冲区中的数据写到文件2中。 - 代码展示:
/************************************************
*文件名称: mycopy.c
*摘 要: 通过命令行传递参数实现两个文件间的复制
*作 者:
*完成日期: 2021年1月29日
*************************************************/
#include <stdio.h>
#include <errno.h>
#include <string.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#define BUFSIZE 1024
#define MSG_STR "hello world\n"
int main(int argc, char *argv[])
{
int fd1 = -1;
int fd2 = -1;
int rv1 = -1;
int rv2 = -1;
int choose = -1;
char buf[BUFSIZE];
char *file1;
char *file2;
if (argc != 3)
{
printf("Error! Right Usage: mycopy file1 file2\n");
printf("for example: mycopy file1.txt file2.txt\n");
return 0;
}
file1 = argv[1];
file2 = argv[2];
fd1 = open(file1, O_RDWR|O_CREAT|O_APPEND, 0666);
if (fd1 < 0)
{
printf("Open file %s failure: %s\n", file1, strerror(errno));
}
fd2 = open(file2, O_RDWR|O_CREAT|O_TRUNC, 0666);
if (fd2 < 0)
{
printf("Open file %s failure: %s\n", file2, strerror(errno));
}
if ( (rv1 = write(fd1, MSG_STR, strlen(MSG_STR))) < 0 )
{
printf("Write %d bytes into file1 failure: %s\n", rv1, strerror(errno));
goto cleanup;
}
memset(buf, 0, sizeof(buf));
lseek(fd1, 0, SEEK_SET);
if ( (rv1 = read(fd1, buf, sizeof(buf))) < 0 )
{
printf("Read data from file1 failure: %s\n", strerror(errno));
goto cleanup;
}
if ( (rv2 = write(fd2, buf, strlen(buf))) < 0 )
{
printf("Write %d bytes into file2 failure: %s\n", rv2, strerror(errno));
goto cleanup;
}
cleanup:
close(fd1);
close(fd2);
return 0;
}
代码详解:
- fd1、fd2分别表示文件1、文件2的文件描述符;rv1、rv2分别表示对文件1、文件2进行操作后的结果返回值;定义一个字符数组用作缓冲区存放从文件1当中读取到的数据。
- 通过命令行将两个文件的文件名传送到函数中,判断传入的参数是否为3,不为3就输出错误提示和用法并退出程序。
- 使用open函数打开文件,当文件不存在时输出错误提示;O_RDWR表示以读写方式打开文件,O_CREAT当文件不存在时创建文件,使用此选项时要在第三个参数说明权限(读4写2执行1),O_APPEND向文件中写入数据时不会覆盖原有数据,在文件尾追加,O_TRUNC覆盖原有数据。
- 使用write函数向文件中写入数据,需要指明向哪个文件中写入数据(即文件名),写入的数据,写入数据的大小。
- 使用read函数从文件中读取数据,需要指明从哪个文件中读取,读取到的数据存在哪儿,读取数据的大小。
- 操作完成后关闭文件。
- 注意:
1、 在向文件中写入数据后,再读取数据时并不会读取到数据,原因是读取数据时是从光标处开始读取,而往文件中写入数据后光标置于文件末尾,自然就不能读取到数据。此时要想读取到数据需要将光标移到文件头。使用lseek函数可以修改光标的位置。
lseek函数用法:
lseek(int fd, int offset, int whence)
//fd为文件描述符,offset表示偏移量
lseek(fd1, 0, SEEK_SET);//将光标移到文件头
lseek(fd1, 1, SEEK_CUR);//将光标移到当前光标的下一个位置
lseek(fd1, 0, SEEK_END);//将光标移到文件尾
lseek(fd1, -1, SEEK_END);//将光标移到倒数第一个字符
2、使用缓冲区时要对缓冲区进行清零
memset(buf, 0, sizeof(buf)); - 运行结果
qianxi@ubuntu1804:~/apue$ gcc mycopy.c
qianxi@ubuntu1804:~/apue$ ./a.out
qianxi@ubuntu1804:~/apue$ cat file1.txt
hhhhhhh
hello world
hello world
qianxi@ubuntu1804:~/apue$ cat file2.txt
hhhhhhh
hello world
hello world
qianxi@ubuntu1804:~/apue$
注:不向文件中写入新的内容
不向文件1中写入hello world 直接将文件1复制到文件2
#include <stdio.h>
#include <errno.h>
#include <string.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#define BUFSIZE 1024
int main(int agrc, char **argv)
{
int fd1=-1;
int fd2=-1;
int rv1=-1;
int rv2=-1;
char buf[BUFSIZE];
char *file1="file1.txt";
char *file2="file2.txt";
fd1=open(file1, O_RDONLY);
if(fd1<0)
{
printf("Open file %s failure: %s\n", file1, strerror(errno));
}
fd2=open(file2, O_RDWR|O_CREAT|O_TRUNC, 0666);
if(fd2<0)
{
printf("Open file %s failure: %s\n", file2, strerror(errno));
}
memset(buf, 0, sizeof(buf));
if( (rv1=read(fd1, buf, sizeof(buf))) <0 )
{
printf("Read data from file1 failure: %s\n", strerror(errno));
goto cleanup;
}
if( (rv2=write(fd2, buf, strlen(buf))) <0 )
{
printf("Write %d bytes into file2 failure: %s\n", rv2, strerror(errno));
goto cleanup;
}
cleanup:
close(fd1);
close(fd2);
return 0;
}
运行结果
qianxi@ubuntu1804:~/apue$ ./a.out
qianxi@ubuntu1804:~/apue$ cat file1.txt
hhhhhhh
hello world
hello world
new file
qianxi@ubuntu1804:~/apue$ cat file2.txt
hhhhhhh
hello world
hello world
new file
qianxi@ubuntu1804:~/apue$