news 2026/5/1 10:33:48

【C语言】之文件操作详解1(流,文件信息区,文件缓冲区,文件的打开与关闭)

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
【C语言】之文件操作详解1(流,文件信息区,文件缓冲区,文件的打开与关闭)

前言:由于文件操作内容篇幅较大,小编将用3篇博客重头到尾详细介绍,争取让新手小白也能看懂并上手,相关链接我会放在文章的结尾,请关注博主的博客不要错过最新内容哦

目录

1.为什么使用文件

2. 文件是什么

2.1程序文件

2.2 数据文件

2.3文件名

3.二进制文件和文本文件

4.文件的打开和关闭

4.1流和标准流

1.流

2.标准流

4.2文件指针

1.文件信息区

2.文件缓冲区(补充)

4.3.如何理解文件信息区,流,文件缓冲区的关系

4.4文件的打开(fopen)

4.5文件的关闭(fclose)

fclose函数注意事项

往期内容:


1.为什么使用文件

如果没有⽂件,我们写的程序的数据是存储在电脑的内存中,如果程序退出,内存回收,数据就丢失了,等再次运⾏程序,是看不到上次程序的数据的,如果要将数据进行持久化的保存,我们可以使用文件

2. 文件是什么

硬盘磁盘上的文件是文件

从文件功能的角度来分类

1.程序文件 2.数据文件

2.1程序文件

程序文件包括

源文件(后缀为.c)

目标文件(windows环境后缀为.obj)

可执行程序(windows环境后缀为.exe)

2.2 数据文件

程序运行时读写的数据存储文件

在以前各章所处理数据的输⼊输出都是以终端为对象的,即从终端的键盘输⼊数据,运⾏结果显示在显示器上

其实有时候我们会把信息输出到磁盘上,当需要的时候再从磁盘上把数据读取到内存中使⽤,这⾥处理的就是磁盘上⽂件

2.3文件名

⼀个⽂件要有⼀个唯⼀的⽂件标识,以便⽤⼾识别和引⽤

⽂件名包含3部分:⽂件路径+文件名主干+文件后缀

例如:E:\code2\learn new c\test 11_25\ test.c

文件路径E:\code2\learn new c\test 11_25\

文件名主干test

文件后缀.c

为了⽅便起⻅,⽂件标识常被称为⽂件名

补充一下相对路径和绝对路径

绝对路径:是从根目录开始写

相对路径:是从当前文件位置开始

.(一个点):代表当前目录

..(两个点):代表上一级目录

这时我们通过..使得test.txt文件出现在learn new c文件下而不是在test12_20内

3.二进制文件和文本文件

根据数据的组织形式,数据⽂件被分为⽂本⽂件和⼆进制⽂件

⼆进制文件:数据在内存中以⼆进制的形式存储,不加转换的输出到外存的⽂件中

文本文件:在存储前转换,以ASCII字符的形式存储的⽂件

⼀个数据在⽂件中是怎么存储的呢?

字符⼀律以ASCII形式存储,数值型数据既可以⽤ASCII形式存储,也可以使⽤⼆进制形式存储

如有整数10000,如果以ASCII码的形式输出到磁盘,则磁盘中占⽤5个字节(每个字符⼀个字节),⽽⼆进制形式输出,则在磁盘上只占4个字节

通过图片发现直接用文本文档打开二进制文件是我们看不懂的乱码,用VS以二进制来查看10000在内存中是以10 27 00 00 小端模式来存储的,说明数据在内存中以⼆进制的形式存储,且不加转换的输出到外存的⽂件中

关于小端存储的内容请看

C语言之数据在内存中的存储4000字超详解

而文本文件则能通过ASII码一一对应上

4.文件的打开和关闭

4.1流和标准流

1.流

C程序针对⽂件、画⾯、键盘等的数据输⼊输出操作都是通过流操作的

⼀般情况下,我们要想向流⾥写数据,或者从流中读取数据,都是要打开流,然后操作

2.标准流

C程序启动时,默认打开三个流
这些流被称作标准流:

stdin标准输入流(从键盘输入)
(scanf函数从此读取数据)
stdout标准输出流(从屏幕输出)
(printf函数向此输出数据)
stderr标准错误流(从屏幕输出)

这三个流的类型都是FILE * ,通常称为文件指针

4.2文件指针

1.文件信息区

每个被使用的文件都在内存中开辟了⼀个相应的文件信息区,⽤来存放文件的相关信息,这些信息是保存在⼀个结构体变量中的。该结构体类型是由系统声明的,取名 FILE.

例如我们打开stdio.h 头⽂件中会有以下的⽂件类型类似的申明,不同编译器大同小异

typedef struct { int level; // 缓冲区"满"或"空"的程度 unsigned flags; // 文件状态标志 char fd; // 文件描述符 unsigned char hold; // 如无缓冲区则不读取字符 int bsize; // 缓冲区的大小 unsigned char *buffer; // 数据缓冲区的位置 // ... 其他编译器相关的字段 } FILE;

通过定义pf一个指向FILE类型数据的指针变量

可以使pf指向某个⽂件的⽂件信息区(是⼀个结构体变量)

通过该⽂件信息区中的信息就能够访问该⽂件

也就是说,通过⽂件指针变量能够间接找到与它关联的⽂件

2.文件缓冲区(补充)

ANSI C 标准采⽤“缓冲文件系统” 处理数据文件的,所谓缓冲⽂件系统是指系统自动地在内存中为程序中每⼀个正在使用的文件开辟⼀块“文件缓冲区”。
缓冲区的大小根据C编译系统决定的

4.3.如何理解文件信息区,流,文件缓冲区的关系

​ 就像是一条连接你的程序(内存)和外部设备(如硬盘上的文件)的高速公路。数据如同车辆,在这条公路上单向或双向行驶(输入/输出)

文件信息区​ 则是这条高速公路的管理中心。这个中心里有一张监控大屏(FILE结构体),上面记录着关键信息:比如当前公路的拥堵状况(缓冲区状态)、最后一辆车开到了哪个位置(文件指针的当前位置)、这条路目前是只允许进货还是只允许出货(文件的打开模式,"r"/"w"等)

文件缓冲区​ 就是高速公路上的服务区或上下匝道。它避免了车辆(数据)直接频繁进出城市(磁盘),而是让它们在服务区集结,然后成批上路或下路,极大地提高了整体通行效率。

三者如何协同工作

1.建立连接:打开文件

当你调用fopen("data.txt", "r")时,系统会进行一系列操作

在内存中创建一个文件信息区FILE结构体实例),并填充初始信息(如文件名、打开模式)

建立与该文件关联的流

分配一块文件缓冲区

返回一个指向该文件信息区的文件指针(如FILE *pf

此后,你对文件的所有操作都通过这个指针来告知系统操作哪个“管理中心”

2.数据传输:读写操作

当你使用fputs("Hello", pf)写入数据时,字符串"Hello"不是直接写入磁盘,而是先被送到文件缓冲区(服务区)暂存

文件信息区会记录当前写入的位置等信息

当缓冲区被填满,或遇到强制刷新(fflush)、关闭文件等操作时,系统才将缓冲区内的数据一次性写入磁盘文件。读取数据的过程类似,数据会从磁盘先被批量读入缓冲区,程序再从缓冲区读取

3.断开连接:关闭文件

调用fclose(pf)是关键一步,它会

确保文件缓冲区中任何未写入的数据被写入磁盘

释放文件缓冲区占用的内存

断开的连接

销毁文件信息区

#include <stdio.h> int main() { // 打开文件:建立流、创建文件信息区和缓冲区 // pf 是指向文件信息区的指针,是操作流的“手柄” FILE *pf = fopen("example.txt", "w"); if (pf == NULL) { perror("文件打开失败"); return 1; } // 通过 pf(操作文件信息区)向流中写入数据 // 数据 "这是一条数据" 会先进入文件缓冲区 fputs("这是一条数据", pf); // 可以调用 fflush 主动将缓冲区数据写入磁盘 // fflush(pf); // 关闭文件:刷新缓冲区、断开流、销毁文件信息区 fclose(pf); pf = NULL; // 良好习惯,避免野指针 return 0; }

关于函数fflush我会在后面讲到如何使用

4.4文件的打开(fopen)

功能:

用于打开文件,建立程序与硬盘文件之间的数据通道

参数:

filename :表示被打开的文件的名字,这个名字可以绝对路径,也可以是相对路径(前面文件名有讲的很详细回去看)

mode :表示对打开的文件的操作方式,具体见下面的表格

返回值:

若文件成功打开,该函数将返回⼀个指向 FILE 对象的指针

若打开失败,则返回 NULL 指针

所以⼀定要 fopen 的返回值做判断,来验证⽂件是否打开成

下面这张图包含了所有文件操作方式

本篇就先讲最基础的三种方式——”r"、“w”、”a".

什么是 “ 读 ” ,什么是 “ 写 ”
“ 读 ”输入数据,将数据从磁盘(文件)中输入到内存中存储
“ 写 ”输出数据,将数据从内存中输出到磁盘(文件)中存储

" r "(只读)

为了输出数据,打开一个已经存在的文本文件,且不会修改原文件

(若文件不存在,会报错)

文件本身存在:

文件本身不存在:

用 perror 函数打印出错误信息
perror("fopen");

这里可以看到,代码报错了,原因就是电脑里没有这个i love you.txt文件,那自然读取不了了

" w "(只写)

为了输出数据,打开一个文本文件,并清空原文件内容
(若不存在,会新建一个文件)

文件本身存在:

现在我们先在test.c文件旁新建一个文件,并输入i love you

接着运行这个代码

#include<stdio.h> int main() { FILE* pf = fopen("test666.txt", "w"); return 0; }

我们会发现,原来我们输入的数据不见了,文件内容被清空了
所以可以看到 ” w " 方式打开文件的特点——会清空原文件的内容

文件本身不存在:

现在我们把test666.txt文件删掉

#include<stdio.h> int main() { FILE* pf = fopen("test666.txt", "w"); return 0; }

再次运行上面那个代码

发现,系统自动给我们新建了一个文件,文件名就是参数
当文件不存在时,就会新建一个文件

" a "(追加)

向文本文件尾部添加数据,且不会修改原文件
(若文件不存在,会新建一个文件)

文件存在:
现在我们先在test.c文件旁新建一个文件,并输入i love you

再用代码进行追加(这里先用到输出操作,后面会讲):

#include<stdio.h> int main() { FILE* pf = fopen("test666.txt", "a"); fputs("too", pf); return 0; }

可以看到,文本文件追加了新的字符串too
但若文件不存在,就直接创建一个文件再输出

4.5文件的关闭(fclose)

功能:

用于关闭文件,删除程序与硬盘文件之间的数据通道

参数:

stream :指向要关闭的流的 FILE 对象的指针

返回值:

成功关闭 stream 指向的流会返回0,否则会返回 EOF

fclose函数注意事项

fclose(pf);
当你关闭了文件时,其指针pf就会变为野指针
故关闭文件文件后,必须立即置为NULL

#include<stdio.h> int main() { FILE* pf = fopen("test.txt", "r"); if (pf == NULL) { perror("fopen"); //打印出错误信息 return 0; //返回状态码 1 表示异常退出 } fclose(pf); pf = NULL;//置为NULL空指针 return 0; }

往期内容:

数据结构的基石之动态内存管理详解

从汇编底层了解函数栈帧的创建与销毁6500字超详解

OK,以上就是全部内容了

若内容对大家有所帮助,可以收藏慢慢看,感谢大家支持

后面还有2篇,敬请期待
本文有若有不足之处,希望各位兄弟们能给出宝贵的意见。谢谢大家!!
本期制作不易希望各位兄弟们能动动小手,三连走一走!!
支持一下(三连必回0.0)

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/5/1 10:06:32

Linly-Talker姿态补偿算法:修复低质量输入图像变形

Linly-Talker姿态补偿算法&#xff1a;修复低质量输入图像变形 在数字人技术快速落地的今天&#xff0c;一个看似简单的问题却长期困扰开发者和用户&#xff1a;为什么我上传的照片生成的虚拟形象总像“歪嘴战神”&#xff1f; 明明只是随手拍了一张自拍照——稍微低头、侧了个…

作者头像 李华
网站建设 2026/4/21 12:38:58

手动插入和删除堆元素(不使用优先队列)

1. 堆的基本原理 堆是一棵完全二叉树。 大根堆&#xff1a;任意节点的值 $\ge$ 其子节点的值&#xff08;堆顶最大&#xff09;。 小根堆&#xff1a;任意节点的值 $\le$ 其子节点的值&#xff08;堆顶最小&#xff09;。 存储方式 我们使用一个数组 heap[] 来存储堆&…

作者头像 李华
网站建设 2026/4/24 9:59:31

PySpark实战 - 2.4 利用Spark SQL实现分组排行榜

文章目录1. 实战概述2. 实战步骤3. 实战总结1. 实战概述 本次实战基于 Spark SQL 对学生成绩数据进行分组 Top3 排行统计。通过读取 HDFS 上的成绩文件&#xff0c;解析姓名与分数&#xff0c;利用窗口函数 ROW_NUMBER() 按学生分组并降序排序&#xff0c;筛选出每人最高三次成…

作者头像 李华
网站建设 2026/4/24 4:20:09

业界人士质疑汽车销量造假,经销商已开始拒绝压库,谁在裸泳?

11月份不少车企公布了可观的销量&#xff0c;然而11月份国内汽车市场零售量却下滑了8.1%&#xff0c;环比也下滑了1.1%&#xff0c;如此情况下很难相信有那么多的车企仍然取得销量的增长&#xff0c;以至于有业界人士指出可能存在销量造假的情况。更为让人吃惊的数据则是12月第…

作者头像 李华
网站建设 2026/4/22 12:46:56

Linly-Talker语音克隆功能详解:3分钟复制你的声音

Linly-Talker语音克隆功能详解&#xff1a;3分钟复制你的声音 在短视频、直播和智能客服泛滥的今天&#xff0c;千篇一律的“机器人音”早已让用户审美疲劳。人们渴望的是有温度的声音——熟悉、亲切、带着个人印记。如果能让数字人用你自己的声音说话&#xff0c;会怎样&#…

作者头像 李华
网站建设 2026/5/1 8:03:11

Linly-Talker支持CUDA核心监控,实时掌握GPU利用率

Linly-Talker支持CUDA核心监控&#xff0c;实时掌握GPU利用率 在生成式AI与数字人技术快速落地的今天&#xff0c;一个看似流畅的虚拟主播背后&#xff0c;往往隐藏着复杂的多模态推理流水线。从语音识别、大模型对话生成&#xff0c;到语音合成和面部动画驱动&#xff0c;每一…

作者头像 李华