文件类型
文件是指以字节的形式存储的数据源,使用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