重点学习内容:
1)什么是文件IO
2)文件操作的主要接口API
3)文件操作的一般步骤
4)文件操作的一些概念
5)什么是文件描述符及其作用
6)一个简单的文件读写实例
1、什么是文件IO
IO就是input/output,输入/输出。文件IO的意思就是读写文件。也称文件IO称之为不带缓存的IO(unbuffered I/O)。
2、文件操作的主要接口API
API(Application Programming Interface),应用程序编程接口函数
Linux常用文件IO接口 open、close、write、read、lseek,我们可以使用man 手册来查询每个函数的使用方法,返回值,传参等等。
man 2 open
man 2 read
man 2 write
man 2 lseek
man 2 close
int open(const char *pathname, int flags);
int open(const char *pathname, int flags, mode_t mode);
ssize_t read(int fd, void *buf, size_t count);
ssize_t write(int fd, const void *buf, size_t count);
off_t lseek(int fd, off_t offset, int whence);
int close(int fd);
如下图open函数:
3、文件操作的一般步骤
1)先open打开一个文件,得到一个文件描述符
2)然后对文件进行读写操作(或其他操作)
3)最后close关闭文件
4、文件操作的一下概念
1)文件平时是存在块设备中的文件系统中的,我们把这种文件叫静态文件。
2)将静态文件的内容从块设备中读取到内存中特定地址管理存放(叫动态文件)。
3)当我们去open打开一个文件时,linux内核做的操作包括:内核在进程中建立了一个打开文件的数据结构,记录下我们打开的这个文件;内核在内存中申请一段内存存放打开的文件。 之后对这个文件的读写操作,都是针对内存中这一份动态文件的,而并不是针对静态文件的。我们对动态文件进行读写后,此时内存中的动态文件和块设备中的静态文件就不同步了,当我们close关闭动态文件时,close内部内核将内存中的动态文件的内容去更新(同步)块设备中的静态文件。
5、什么是文件描述符及其作用
1) 文件描述符就是用来区分一个程序打开的多个文件的。
2) 文件描述符的作用域就是当前进程,出了当前进程这个文件描述符就没有意义了。
6、一个简单的文件读写实例
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#define FILENAME "a.txt"
int main(void)
{
int fd = -1;
int Wfd = 0;
int Rfd = 0;
char Writebuff[13]={"I_love_Linux!"};
char Readbuff[100]={0};
// int open(const char *pathname, int flags);
fd = open(FILENAME,O_RDWR);
if(fd < 0)
{
perror("open");
return 0;
}
//ssize_t write(int fd, const void *buf, size_t count);
Wfd = write(fd,Writebuff,13);
if(Wfd < 0)//写入失败
{
perror("write");
return 0;
}
printf("写入了%d 个数据\n",Wfd);
//sleep(1);
//ssize_t read(int fd, void *buf, size_t count);
Rfd = read(fd,Readbuff,13);
if(Rfd < 0)
{
perror("read");
return 0;
}
printf("读取了%d 个数据\n",Rfd);
printf("读取到的数据为%s \n",Readbuff);
close(fd);
return 0;
}
这个代码单独读或单独写都没有问题,但是连接起来先写入再来读取就不行,运行结果如下:
读取成功了,但是却为0,很是纳闷,我们明明是O_RDWR 可读可写模式就是不行,但是发现读在写的前面,写是可以成功的,如下图:
但是还是有点奇怪,他居然是追加的写到了原有数据的后面,我们并没有设置追加写入O_APPEND,
对于问题:先写入再读取为0,和先读取再写入变成追加模式
最后测试发现写完数据或读完数据就关闭文件,然后再open打开再去读取数据或或写入数据就OK了。
个人理解为当你写入文件时没有保存文件(即没执行close(fd))这个时候去读取数据肯定是空的,即出现读取数据为0,而对于先读取数据时,数据已经在一个读取的状态了没法覆盖所以就形成了追加模式。
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#define FILENAME "a.txt"
int main(void)
{
int fd = -1;
int Wfd = 0;
int Rfd = 0;
char Writebuff[13]={"fffffffffffff"};
char Readbuff[100]={0};
// int open(const char *pathname, int flags);
fd = open(FILENAME,O_RDWR);
if(fd < 0)
{
perror("open");
return 0;
}
//ssize_t write(int fd, const void *buf, size_t count);
Wfd = write(fd,Writebuff,13);
if(Wfd < 0)//写入失败
{
perror("write");
return 0;
}
printf("写入了%d 个数据\n",Wfd);
close(fd);
fd = open(FILENAME,O_RDWR);
if(fd < 0)
{
perror("open");
return 0;
}
//ssize_t read(int fd, void *buf, size_t count);
Rfd = read(fd,Readbuff,13);
if(Rfd < 0)
{
perror("read");
return 0;
}
printf("读取了%d 个数据\n",Rfd);
printf("读取到的数据为%s \n",Readbuff);
close(fd);
return 0;
}
这个就可以实现边写边读取,对于先读后写修改一下就可以了。