初级文件IO——open打开文件成功后行为分析

前言

如果open打开失败的话(比如文件不存在就会导致失败),open啥也不会干就直接返回了。但是如果open将文件打开成功的话,open具体做了哪些事情呢?

open成功后行为

记录打开文件的信息

程序运行起来后就是一个进程了,OS会创建一个task_struct的结构体,记录进程运行时的各种信息,比如所打开文件的相关信息。

open将文件成功打开后,在task_struct中又会创建一些结构体(数据结构),用于记录当前进程目前所开文件的信息,后续所有的文件操作,都需要依赖于这些信息,其中就包括指向打开文件的文件描述符。

文件描述符表files_struct

申请内存空间

open函数会申请一段内存空间(内核缓存),后续读写文件时,用于临时缓存读写文件时的数据。

什么是缓存?

就是开辟的一段内存空间,比如char buf[100],这就是一段100字节的缓存空间,用于临时存放中转的数据。

为什么叫内核缓存?

open是OS所提供的系统函数,属于OS内核的一部分,所以open函数所开辟的缓存空间,就是内核缓存。

#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>

int main(void)
{
    int fd = 0;

    fd = open("./file.txt", O_RDWR);
    if(-1 == fd)
    {
        printf("open fail\n");
        return 0;
    }
    else
    {
        printf("open ok\n");
    }

    char buf1[] = "hello world";
    write(fd, (void *)buf1, 11);

    lseek(fd, 0, SEEK_SET);

    char buf2[30] = {0};
    read(fd, buf2, sizeof(buf2));
    
    printf("buf2 = %s\n", buf2);    
    
    close(fd);
    
    return 0;
}

例子程序中,我定义了buf1和buf2这两个数组,这两个数组是我自己的应用程序定义的,因此就叫应用缓存。

open为什么要开内核缓存空间?

内存读写速度 > 磁盘读写速度的,有了在内存中开辟的内核缓存后,上层读写数据时,会直接读写缓存,速度会很快,至于缓存与磁盘上文件数据的交换,就留给下层去做,这样可以节省上层操作的时间。

注意:open时只是开辟了内核缓存空间,里面并没有数据,只有当进行读写数据时,才会缓存读写的数据。

读写时,缓存间数据的流动是怎样的?

详论文件描述符

什么是文件描述符

open成功就会返回一个非负整数(0、1、2、3...)的文件描述符,比如我们示例程序中open返回的文件描述符是3。文件描述符指向了打开的文件,后续的read/write/close等函数的文件操作,都是通过文件描述符来实现的。

文件描述符表与task struct关系

进程表与文件描述符表

文件描述符池

每个程序运行起来后,就是一个进程,系统会给每个进程分配0~1023的文件描述符范围,也就是说每个进程打开文件时,open所返回的文件描述符,是在0~1023范围中的某个数字。

0~1023这个范围,其实就是文件描述符池。

1023这个上限可不可以改?

可以,但是没有必要,也不会介绍如何去改,因为一个进程基本不可能出现,同时打开1023个文件的情况,文件描述符的数量百分百够用。

open返回文件描述符规则

open返回文件描述符池中,当前最小没用的哪一个。进程一运行起来,0/1/2默认就被使用了,最小没被用的是3,所以返回3。如果又打开一个文件,最小没被用的就应该是4,所以open返回的应该是4。

文件关闭后,被文件用的描述符怎么办

会被释放,等着下一次open时,被重复利用。

open的文件描述符 与 fopen的文件指针

open

Linux 的系统函数(文件io函数)。open成功后,返回的文件描述符,指向了打开的文件。

fopen

C库的标准io函数 

#include <stdio.h>                
FILE *fopen(const char *path, const char *mode);

fopen成功后,返回的是FILE *的文件指针,指向了打开的文件。

对于Linux的C库来说,fopen 这个C库函数,最终其实还是open函数来打开文件的。fopen只是对open这个函数做了二次封装。见下图

也就是说,fopen的文件指针,最终还是会被换成open的文件描述符,然后用于去操作打开的文件。

 

 

 

转载于:https://www.cnblogs.com/kelamoyujuzhen/p/9638710.html

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值