博客园  :: 首页  :: 新随笔  :: 联系 :: 订阅 订阅  :: 管理

Linux编程-FILE结构体与文件描述符

Posted on 2023-03-14 07:03  乔55  阅读(202)  评论(0编辑  收藏  举报

FILE结构体基本概念

// FILE结构体成员
struct _iobuf {  
        charchar *_ptr;         //文件输入的下一个位置  
        int   _cnt;             //当前缓冲区的相对位置  
        charchar *_base;        //基础位置(文件的起始位置)  
        int   _flag;            //文件标志  
        int   _file;            //文件的有效性验证  
        int   _charbuf;         //检查缓冲区状况,如果无缓冲则不读取  
        int   _bufsiz;          //当前缓冲区有效大小  
        charchar *_tmpfname;    //临时文件名  
        };  
typedef struct _iobuf FILE;

// 主要包括三部分:文件描述符、文件指针、IO缓冲区

文件描述符

  • 文件描述符概述
    • 文件存储在磁盘或内存当中,对于内核来讲,所有打开的文件都必须通过文描引用
    • 当打开或创建一个新文件时,内核向进程返回一个文描
    • 当读写一个文件时,使用open或creat返回的文描来标识该文件,将其作为参数传传给read/write
    • 通俗地讲,存在磁盘中的文件想要被进程使用,需要内核向进程返回标识该文件的文描,才可使用
  • 文件描述符的特点
    • 文件描述符索引到对应的文件,文件描述符位于内核区的PCB块中
    • 文件描述符是一个百负整数值,所有打开的文件从小到大,依次构成文描数组的下标
    • 在文件描述符数组中有一个对应的指针,该指针指向一个文件结构体
    • 我们不应该纠结于该结构,我们只要拿到文件描述符fd,来访问文件就足够了
  • 文件描述符的特殊关联
    • UNIX系统shell把文描0与进程的标准输入(STDIN_FILENO)相关联,
    • UNIX系统shell把文描1与进程的标准输出(STDOUT_FILENO)相关联
    • UNIX系统shell把文描0与进程的标准输入(STDERR_FILENO)相关联,均默认打开
      • 关闭0,则无法从键盘输入。且0对应的文件描述符资源被回收,再打开一个新的文件,该文件的文件描述符为0
      • 关闭1,则无法将内容显示在显示器上。再打开新文件同上
      • 关闭2,无法将错误输出到显示器上。再打开新文件同上

文件读写位置指针

  • 操作文件指针的函数请查看此帖:lseek
  • 刚打开文件时指向文件的起始位置

IO缓冲区

  • 更多缓冲区知识请查看此帖:缓冲区

  • IO缓冲区概述

    • 是一个内存地址,通过该地址能找到一块默认大小为8k的内存块
    • C库函数都给我们提供了IO缓冲区,在以下条件满足时,才将缓冲区的内容写入到磁盘文件中
      • 强制刷新
        • int fflush(FILE *stream);成功返回0,否则返回EOF,并设置errno值
        • printf("\n");
      • 正常退出
        • 正常关闭文件:fclose(fp);
        • 主函数中遇到return
        • 主函数中遇到exit
  • 为什么要缓冲区

    • 减少对磁盘的操作次数。若读一个字节,写一个字节,会频繁访问磁盘,效率极低
    • 磁盘(一般是机械硬盘)的读取寻道和写入寻道时间是毫秒级,内存的则是纳秒级别
    • 2者相差了\(10^6\)倍,即百万倍,差别还是很大滴