《基础IO》

【一】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之后便出现了两份代码和两份数据,缓冲区中的数据会直接输入到文件中,但是系统调用的数据本就直接输入到了文件,缓冲区中就不存在了,这也就是出现了一个输入的原因。

以上就是这期的全部内容了,如果有问题的话还请位于评论区斧正,如果没有问题的话,还请给个一件三连,毕竟码字不易。 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值