Linux(三)文件描述符和FILE结构体

文件描述符

在我们介绍文件描述符之前。我们先来看一下
系统调用接口:write,read,close,open,lseek,下面我们来尝试用下open系统调用接口。
这里写图片描述
我们可以看到,我们通过open创建一个文件给它权限0644
接下来我们写一个while循环通过write系统调用将我们的msg写进myfile这个文件里
这里写图片描述

open参数的介绍:
O_RDONLY:只读打开
O_WRONLY:只写打开
O_RDWR:读写打开
这三个量必须指定一个,且必须指定一个
O_CREAT:如果文件不存在,则创建它。需要使用mode选项指明文件的访问权限。
O_APPEND:追加写

返回值:
成功返回新打开文件的描述符
失败返回-1;

文件描述符 fd
Linux进程默认情况下会有三个缺省打开的文件描述符,分别是标准输入0,标准输出1,标准错误2。
0,1,2 对应的设备一般是:键盘,显示器,显示器。
我们现在知道,文件描述符就是从0开始的小整数。当我们打开文件时,操作系统在内存中要创建相应的数据结构来描述目标文件,于是就有了file结构体。表示一个已经打开的文件对象。而进程执行open系统调用,所以必须让进程和文件关联起来。每个进程都有一个指针*file,指向一张表files_struct,该表最重要的部分就是包含一个指针数组,每个元素都是一个指向打开文件的指针!所以,本质上,文件描述符就是该数组的下标。所以只要拿着文件描述符就可以找到对应的文件。

文件描述符的分配规则
直接看代码!
这里写图片描述
这里写图片描述
输出发现fd:3
当我们关闭0或者2,再看
这里写图片描述
这时我们就会发现结果是fd:0。说明文件描述符的分配规则:在file_struct数组当中,找到当前没有被使用的最小的一个下标做为新的文件描述符

输出重定向
我们在前面将1关闭,即close(1);
然后我们就会发现,本来应该输出到显示器上的内容,输出到了文件myfile里面其中fd=1;这种现象叫做输出重定向。常见的重定向有:>,>>,<
重定向的本质是什么呢?
printf是C库中的IO函数,一般往stdout中输出,但是stdout底层访问文件的时候,找的还是fd:1,但此时,fd:1下标所表示的内容,已经变成了myfile的地址,不再是显示器文件的地址,所以输出的任何消息都会往文件中写入,进而完成输出重定向。

FILE

因为IO 相关函数与系统调用接口对应,并且库函数封装系统调用,所以本质上,访问文件都是通过fd访问。所以C库中的FILE结构体内部,必定封装了fd。

#include<stdio.h>
#include<string.h>
int main()
{
    const char *msg0 = "hello printf\n";
    const char *msg1 = "msg1,strlen(msg0),1,stdout";
    write(1,msg2,strlen(msg2));
    fork();
    return 0;
}

输出结果是

hello printf
hello fwrite
hello write

但是我们对进程进行输出重定向./hello>file,我们发现结果变成了:

hello write
hello printf
hello fwrite
hello printf
hello fwrite

除了write其他都输出了两次,一般C库函数写入文件时是全缓冲的,而写入显示器是行缓冲。printf,fwrite库函数会自带缓冲区,当发生重定向到普通文件时,数据的缓冲方式由行缓冲变成了全缓冲。
而我们放在缓冲区中的数据,就不会被立即刷新,甚至fork之后,但是进程退出之后,会统一刷新,写入文件当中。
但是fork的时候,父子数据会发生写时拷贝,所以当你父进程准备刷新的时候,子进程也就有了同样的一份数据,随即产生两分数据。
write没有变换,说明没有所谓的缓冲。
综上所述
printf,fwrite库函数都会自带缓冲区,而write系统调用没有带缓冲区,我们所说的缓冲区都是用户级缓冲区。这个缓冲区是由C标准库提供的。因为write没有缓冲区,所以我们可以知道,该缓冲区是二次加上的

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值