1. 文件的基本概念
文件:存放在磁盘空间中的一段数据的集合,是操作系统管理数据的基本单位。
2. 文件操作的三个基本步骤
- 打开文件:建立程序与文件之间的连接
- 读写文件:对文件内容进行读取或写入操作
- 关闭文件:断开程序与文件的连接,释放资源
3. ASCII码文件与二进制文件
ASCII码文件:一种特殊的二进制文件,文件中的每个字符都是能够显示在终端的ASCII码字符。
- 常见类型:文本文件、程序源代码
二进制文件:文件中包含一些不能在终端直接显示的ASCII码字符。
- 常见类型:图片、音视频、压缩包
4. 标准IO函数接口
4.1 fopen函数
流(Stream):有方向性、具有连续性的数据通道。
三个标准流会随着程序的执行被默认打开:
stdin:标准输入流stdout:标准输出流stderr:标准错误流
函数原型:
FILE *fopen(const char *pathname, const char *mode);功能:打开pathname对应的文件,并与之建立一个流。
参数:
pathname:要打开的文件路径字符串首地址mode:打开文件的方式"r":只读。文件不存在报错,文件存在只读打开"r+":读写。文件不存在报错,文件存在读写打开"w":只写。文件不存在创建,文件存在清空,只写打开"w+":写读。文件不存在创建,文件存在清空,写读打开"a":追加只写。文件不存在创建,文件存在追加只写打开"a+":追加读写。文件不存在创建,文件存在追加读写打开
返回值:
- 成功:返回创建的流的空间首地址(FILE指针)
- 失败:返回NULL
4.2 fclose函数
函数原型:
int fclose(FILE *stream);功能:关闭流。
参数:stream:文件流指针
返回值:
- 成功:返回0
- 失败:返回EOF
5. 缓存机制
标准IO是有缓存的IO,用户调用标准IO函数后,数据先进入缓存区,满足刷新条件时才将数据传递给内核。
缓存类型:
5.1 全缓存
- 缓存区大小:4K(4096字节)
- 刷新条件:
- 缓存区满刷新
- 使用fflush强制刷新
- 程序结束或fclose刷新
- 适用场景:与文件建立的流都为全缓存
5.2 行缓存
- 缓存区大小:1K(1024字节)
- 刷新条件:
- 缓存区满刷新
- 使用fflush强制刷新
- 程序结束或fclose刷新
- 遇到
\n刷新
- 适用场景:与终端建立的流(stdin、stdout)
5.3 不缓存
- 缓存区大小:0K(立即刷新)
- 适用场景:出错处理、人机交互、实时性要求高的场景
- 示例:stderr
6. 文件读写函数接口
6.1 fputc函数
函数原型:
int fputc(int c, FILE *stream);功能:将字符c写入流中。
参数:
c:要写入的字符stream:文件流指针
返回值:
- 成功:返回写入字符的ASCII码值
- 失败:返回EOF(-1)
练习:利用fputc将"hello world"写入a.txt文件中
6.2 fgetc函数
函数原型:
int fgetc(FILE *stream);功能:从流中读取一个字符。
参数:stream:文件流指针
返回值:
- 成功:返回接收字符的ASCII码值
- 失败:返回EOF
- 读到文件末尾:返回EOF
练习:编写程序统计某个指定文件的行数
7. 其他常用文件读写函数
- fputs/fgets:字符串读写
- fprintf/fscanf:格式化读写
- fwrite/fread:二进制读写
8. 更多文件操作函数详解
8.1 fprintf函数
函数原型:
int fprintf(FILE *stream, const char *format, ...);功能:将格式化的字符串写入stream流中。
参数:
stream:文件流指针format:格式化字符串空间首地址...:可变参数列表
返回值:
- 成功:返回打印在终端的字符个数
- 失败:返回负数
8.2 fputs函数
函数原型:
int fputs(const char *s, FILE *stream);功能:将s指向的字符串写入stream流中。
参数:
s:要写入字符串空间的首地址stream:文件流指针
返回值:
- 成功:返回非负整数
- 失败:返回EOF
8.3 fgets函数
函数原型:
char *fgets(char *s, int size, FILE *stream);功能:从流中读取一行字符串。
参数:
s:读取字符串存入空间的首地址size:最多读取字符的个数stream:文件流指针
返回值:
- 成功:返回s空间地址
- 失败或读到文件末尾:返回NULL
8.4 fwrite函数
函数原型:
size_t fwrite(const void *ptr, size_t size, size_t nmemb, FILE *stream);功能:向流中写入nmemb个对象,每个对象size个字节,数据来自ptr指向的空间。
参数:
ptr:写入数据空间首地址size:每个数据对象的大小nmemb:对象个数stream:文件流指针
返回值:
- 成功:返回实际写入对象的个数
- 失败:返回0
8.5 fread函数
函数原型:
size_t fread(void *ptr, size_t size, size_t nmemb, FILE *stream);功能:从流中读取nmemb个对象,每个对象size个字节,存放在ptr指向的空间中。
参数:
ptr:存放数据空间的首地址size:读取对象的大小nmemb:读取对象的个数stream:文件流指针
返回值:
- 成功:返回读取对象个数
- 失败或读到末尾:返回0
练习:利用fread和fwrite实现将源图片中的内容拷贝到目的文件中
8.6 fseek函数
函数原型:
int fseek(FILE *stream, long offset, int whence);功能:重新设置流的偏移量。
参数:
stream:文件流指针offset:偏移量whence:SEEK_SET:定位到文件开头SEEK_CUR:定位到当前位置SEEK_END:定位到文件末尾
返回值:
- 成功:返回0
- 失败:返回-1
8.7 ftell函数
函数原型:
long ftell(FILE *stream);功能:获得流的偏移量。
8.8 rewind函数
函数原型:
void rewind(FILE *stream);功能:重新将流偏移量定位到开头。
练习:编写一个程序获得文件的长度
9. 综合练习
作业1:
- 编写程序从给定的src.bmp图片中读取图片的宽度和高度,并打印
- 从终端输入一个单词,打印出该单词的含义