文件类型
文件是指以字节的形式存储的数据源,使用C语言将文件数据以输出输出的形式处理叫做文件处理。
文件在C语言中以两种形式存在:
- 文本文件:文本文件是简单的文件类型,这些文件内容以 ASCII 字符格式存储信息。
- 二进制文件:二进制文件以 0 和 1 的二进制格式存储数据,不是人类可读的文件
文件指针
文件指针 (FILE) 是一种数据类型,是被定义在 stdio.h 中的一种结构体,包含了文件的一些信息
| |
文件指针通常被用于处理正在访问的文件,fopen() 是用于打开文件并返回文件的 FILE 指针,而后通过文件只恨进行I/O操作。fopen() 会发生下列事件:
- 文件的内容被加载到缓冲区(操作系统层面)
- 在内存中创建 FILE 的数据结构体,并返回这个结构体指针
文件处理函数
| 函数 | 功能 |
|---|---|
| fopen() | 打开现有文件或新文件 |
| fprintf() | 将数据写入打开的文件 |
| fscanf() | 读取文件中数据 |
| fputc() | 向文件写入一个字符 |
| fgetc() | 从文件中读取一个字符 |
| fclose() | 关闭打开的文件 |
| fseek() | 设置文件指针的位置 |
| fputw() | 将一个整数写入到文件 |
| fgetw() | 从文件中读取一个整数 |
| ftell() | 文件指针的当前位置 |
| rewind() | 设置文件指针位置为初始位置 |
| fread() | 读取文件内容(二进制与文本) |
| fwrite() | 向文件写入内容(二进制与文本) |
| feof() | 是否到达文件结尾 非0 True 到达文件结尾 0 False 没有到达文件结尾 |
fscanf VS fgets
- fscanf读取的是字符,fgets读取的是字符串
- fgets读取换行符结束,fscanf读取到空白就结束,不用换行符
- fgets以行为单位,fscanf以字符为单位(参数2匹配的模式)
- fscanf每次会判断是否匹配,如不匹配则提前退出读取
| |
文件的打开模式
| 模式 | 含义 | 当文件不存在时处理方法 |
|---|---|---|
| r | 只读方式打开文件 | 当文件路径不存在时fopen()返回NULL |
| rb | 以只读方式打开二进制文件 | 当文件路径不存在时fopen()返回NULL |
| w | 写入方式 | 如果文件存在则覆盖,如果不存在则创建新文件 |
| wb | 写入方式(二进制模式) | 如果文件存在则覆盖,如果不存在则创建新文件 |
| a | 打开文件并向结尾追加内容 | 如果文件路径不存在则创建新文件 |
| ab | 打开文件并向结尾追加内容(二进制模式) | 如果文件路径不存在则创建新文件 |
| r+ | 读写方式打开文件 | 当文件路径不存在时fopen()返回NULL |
| rb+ | 读写方式打开文件(二进制模式) | 当文件路径不存在时fopen()返回NULL |
| w+ | 读写方式打开文件 | 如果文件存在则覆盖,如果不存在则创建新文件 |
| wb+ | 读写方式打开文件(二进制模式) | 如果文件存在则覆盖,如果不存在则创建新文件 |
| a+ | 追加和读取 | 如果文件路径不存在则创建新文件 |
| ab+ | 追加和读取(二进制模式) | 如果文件路径不存在则创建新文件 |
文件操作的步骤
打开文件
fopen()( FILE *Pointer)读写文件
fputc,fgetc,fputs,fgets,fread,fwrite….关闭文件 fclose()
打开文件
| |
例如
| |
关闭文件
| |
读/写文件
向文本文件中写入数据
| |
从文本文件中读取内容
| |
写入二进制文件
二进制文件的读取使用,fwrite()/fread()函数,通常情况下二进制文件读取没有意义,只是做类似文件拷贝的操作。
fwrite(addressData, sizeData, numbersData, pointerToFile);
- addressData:写入磁盘的数据的地址
- sizeData:要写入磁盘的数据大小
- numbersData:写出的数据个数
- pointerToFile:FILE指针
- return:
- 成功:参数3的大小
- 失败:0
Notes:通常参数2为1,参数3为写入的总大小。 参2 * 参3 = 写入的总大小
| |
从二进制文件读取数据
fread(addressData, sizeData, numbersData, pointerToFile);:
- addressData:读取到的数据存储的位置
- sizeData:一次读取的字节数
- numbersData:读取次数
- pointerToFile:文件指针
- return:
- 成功:参数3的大小
- 失败:0
- 到达文件结尾:feof(fp)为真
| |
缓冲区
缓冲区是操作系统的内存空间中的一部分。操作系统在内存空间中预留了一定的存储空间,在输入或输出达到一定量后进行I/O操作,这部分空间就叫做缓冲区。
程序在启动时,预定义了三种缓冲区,不需要显式开启:
- 标准输入 (stdin):
- 标准输出 (stdout):
- 标准错误 (stderr):标准错误是一个无缓冲
stdio.h 库中提供了三种缓冲模式 [1]:
- 无缓冲 (unbuffered):写入到无缓冲的数据会立即被写入到文件
- 行缓冲 (line buffered):当遇到换行符,此类缓冲区内容会被写入到文件
- 全缓冲 (fully buffered):缓冲区满或以任意大小的块被写入到文件
可以通过库函数setvbuf(), setbuffer(), setbuf() 三者之一设置 stdio 的缓冲模式,例如
| |
可以使用库函数 fflush() 手动刷新缓冲区 [2],例如
| |
如果,全缓冲模式下,缓冲区没满也没刷新,那么只有在文件关闭时, 缓冲区会被自动刷新(写入到文件)
Tips:内存的隐式回收:关闭文件、刷新缓冲区、释放malloc
Reference
[1] IO cache