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者相差了倍,即百万倍,差别还是很大滴
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 【自荐】一款简洁、开源的在线白板工具 Drawnix
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY
· Docker 太简单,K8s 太复杂?w7panel 让容器管理更轻松!