【一】C文件接口
我们使用C语言向文件写入东西的时候,基本上的套路都是先打开文件,然后调用C的文件接口,向文件中输入相应的数据,然后关闭文件。
a.size_t fwrite( const void *buffer, size_t size, size_t count, FILE *stream );
b.ssize_t s = fread(buf, 1, strlen(msg), fp);
【二】c文件的三个标准输入输出流
C默认会打开三个输入输出流,分别是stdin,stdout,stderr,换成中文来说就是标准输入,标准输出,标准错误。
仔细观察会发现,这三个流的类型都是FILE*,fopen,返回值类型,文件指针。
打开文件若干种方式:
r:仅以读的方式去打开这个文件
r+:以读写的方式打开这个文件,如果不存在就报错
w:仅以写的方式去打开这个文件
w+:以读写的方式打开这个文件,如果这个文件不存在,那么就去创建这个文件
a:以追加的方式打开文件,如果文件不存在就创建文件
a+:以读和追加的方式去打开文件,如果文件不存在就创建文件,追加的位置在末尾,读的位置在开头。
【三】系统文件I/O
操作文件,除了调用上面的C接口以外(当然C++也有接口,其他语言也有接口),我们还可以采用系统接口来进行文件访问,接下来看一段代码。
接口介绍:open
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
int open(const char *pathname, int flags);
int open(const char *pathname, int flags, mode_t mode);
pathname: 要打开或创建的目标文件
flags: 打开文件时,可以传入多个参数选项,用下面的一个或者多个常量进行“或”运算,构成flags。
参数:
O_RDONLY: 只读打开
O_WRONLY: 只写打开
O_RDWR : 读,写打开
这三个常量,必须指定一个且只能指定一个
O_CREAT : 若文件不存在,则创建它。需要使用mode选项,来指明新文件的访问权限
O_APPEND: 追加写
返回值:
成功:新打开的文件描述符
失败:-1
mode_t理解:直接man手册,比啥都清楚,其实主要就是你创建的文件权限
open:函数具体使用哪个,和具体应用场景相关,如目标文件不存在,需要open创建,则第三个参数表示创建文件的默认参数,否则,使用两个参数的open。
open函数返回值:
在认识返回值之前,先来认识一下两个概念:系统调用和库函数
上面的fopen,fclose,fread,fwrite都是C标准库中的函数,我们称之为库函数
而open,close,read,write,lseek都是属于系统提供的接口,称之为系统调用接口
所以f#系列的函数都是对系统调用的封装,方便我们进行二次开发
【四】文件描述符fd
其实文件描述符本质上就是一个小整数
0&1&2
Linux进程下默认情况下会有三个默认打开的文件描述符,分别是标准输入0,标准输出1,标准错误2,分别对应的物理设备是键盘,显示器,显示器。
文件描述符:
而现在知道,文件描述符就是从0开始的小数,当我们打开文件时,操作系统要在内存中创建相应的数据结构来描述目标文件,于是就有了file结构体。表示一个已经打开的文件对象,而执行open系统调用,所以必须让进程和文件关联起来,每个进程都有一个*files,指向一个files_struct,该表最重要的部分就是保函一个指针数组,每个元素都是一个指向打开文件的指针!所以本质上就是该数组的下标,所以只需要找到该数组的下标,所以只要拿着文件的描述符,就可以找到相对应的文件。
【五】重定向
含义:Linux重定向是指修改原来默认的一些东西,对原来系统命令的执行方式进行改变。
看一段代码:
此时,我们发现,原本输出到显示器上面的内容,却输入到了文件myfile当中,其中,fd=1,这种现象叫做输出重定向,常见的重定向有:>,>>,<
那重定向的本质是什么呢?
修改文件描述符fd下标,对应的struct file* 的内容,奖其替换成目标文件的地址。
【六】FILE
因为IO相关函数与系统调用接口对应,并且库函数封装系统调用,所以本质上,访问文件都是fd访问的,所以C库当中的FILE结构体内部,必定封装了fd。
【七】缓冲区的概念
看以下代码:
出现的结果:
你会发现有一个仅仅出现了一次,这是为什么呢?历其实就是c的库函数会自带缓冲区,而系统调用没有缓冲区,当你fork之后便出现了两份代码和两份数据,缓冲区中的数据会直接输入到文件中,但是系统调用的数据本就直接输入到了文件,缓冲区中就不存在了,这也就是出现了一个输入的原因。
以上就是这期的全部内容了,如果有问题的话还请位于评论区斧正,如果没有问题的话,还请给个一件三连,毕竟码字不易。