01. 标准库函数与系统调用对比
| 系统调用 | 标准I/O库 |
|---|---|
| open/read/write/close | fopen/fread/fwrite/fclose |
| 文件描述符(fd) | 文件指针(FILE*) |
| 无缓冲,直接系统调用 | 自动缓冲管理 |
| 每次操作触发系统调用 | 减少系统调用次数 |
| <fcntl.h> <unistd.h> | <stdio.h> |
系统调用封装层:
标准库函数在保证功能的前提下能够提升性能,扩展专属功能。
fopen与fread设计系统调用示例:
数据交换方式:
读写操作异同
系统调用族:
ssize_t read(int fd, void *buf, size_t count);
ssize_t write(int fd, const void *buf, size_t count);
//文件定位
off_t lseek(int fd, off_t offset, int whence);
标准库函数:
//文件读写
size_t fread(void *ptr, size_t size, size_t nmemb, FILE *stream);
size_t fwrite(const void *ptr, size_t size, size_t nmemb, FILE *stream);
int fgetc(FILE *stream);
int fputc(int c, FILE *stream);
char *fgets(char *s, int size, FILE *stream);
int fputs(const char *s, FILE *stream);
//文件查找
int fseek(FILE *stream, long offset, int whence);
long int ftell(FILE *stream);
void rewind(FILE *stream);
02. 系统调用文件操作
2.1 文件打开open()
系统调用 open()
向文件描述符fd写入数据。
int open(const char *pathname, int flags, mode_t mode);
- 参数说明:
flags:必选其一:O_RDONLY,O_WRONLY,O_RDWR- 可选标志(一个
/多个):O_CREAT(创建),O_APPEND(追加),O_TRUNC(清空)等 mode:文件权限umask(八进制数,如0666)
2.2 文件关闭close()
int close(int fd);
2.3 文件写入write()
从用户空间buf读取count个字节数据写到fd指向的文件中。
ssize_t write(int fd, const void *buf, size_t count);
- 参数:
fd:文件描述符buf:被写入的数据缓冲区count:要写入的字节数
- 返回值:成功返回写入的字节数,失败返回-1
2.4 文件读取read()
从文件描述符fd指向的文件中读取count字节数据放到buf缓冲区内。
ssize_t read(int fd, const void *buf, size_t count);
- 参数:
fd:文件描述符buf:读出的数据存放位置count:要写入的字节数
- 返回值:成功返回写入的字节数,失败返回-1
ssize_t指有一个-1错误码表示失败的情况。
2.5 文件定位lseek()
off_t lseek(int fd, off_t offset, int whence);
- whence参数:
- SEEK_SET:文件开头
- SEEK_CUR:当前位置
- SEEK_END:文件结尾
返回值:成功: 返回新的offset。失败:返回(off_t)-1
啊
文件操作基础流程: 打开文件 → 读写操作 → 关闭文件
03.C文件的打开与关闭
3.2 二进制文件语文本文件
如数字63,在文本文件中表示6和3两个ASCII字符表示
'6' → 0x36
'3' → 0x33
文件内容:36 33//与字符编码一致
而在二进制文件中将63直接转化成二进制形式
//在32位下,int类型,
//小端对齐(字节内部顺序不变,储存顺序与阅读顺序相反即:00 00 00 3F是我们转换的二进制内容)
//需考虑字节序/对齐
3F 00 00 00 // 63的十六进制是0x3F
3.2 文件的打开fopen()
//文件打开
FILE *fopen(const char *filename, const char *mode);
- 功能:打开文件并返回文件指针
- 参数:
pathname:文件路径mode:打开模式(“r”, “w”, “a”, “r+”, “w+”, "a+"等)
- 返回值:成功返回FILE指针,失败返回NULL
打开模式: 输出->到磁盘
| 模式字符串 | 含义 | 如果指定文件不存在 |
|---|---|---|
| “r” | 只读 - 打开文本文件输入数据 | 出错 |
| “w” | 只写 - 创建文本文件输出数据 | 建立新文件 |
| “a” | 追加 - 向文本文件尾添加数据 | 建立新文件 |
| “rb” | 只读 - 打开二进制文件输入数据 | 出错 |
| “wb” | 只写 - 创建二进制文件输出数据 | 建立新文件 |
| “ab” | 追加 - 向二进制文件尾添加数据 | 建立新文件 |
| “r+” | 读写 - 打开文本文件进行读写 | 出错 |
| “w+” | 读写 - 创建新文本文件进行读写 | 建立新文件 |
| “a+” | 读写 - 打开文本文件在文件尾读写 | 建立新文件 |
| “rb+” | 读写 - 打开二进制文件进行读写 | 出错 |
| “wb+” | 读写 - 创建新二进制文件进行读写 | 建立新文件 |
| “ab+” | 读写 - 打开二进制文件在文件尾读写 | 建立新文件 |
注意:
w系列模式("w","w+","wb","wb+"):强制清空。a系列模式("a","a+","ab","ab+"):追加写入。r系列模式("r","r+","rb","rb+"):保留内容(文件必须存在)
示例:fopen("log.txt", "r")
3.3 文件的关闭fclose()
int fclose(FILE *stream);
- 成功返回
0,失败返回EOF - 必须调用以避免资源泄漏
04. 文件顺序读写
4.1字符读写
int fgetc(FILE *stream); // 读取一个字符
int fputc(int c, FILE *stream); // 写入一个字符到流中
4.2字符串读写
int fputs(const char *str, FILE *stream); // 写入字符串到流中
特性:
- 函数在遇到第一个
\0时就停止

char *fgets(char *str, int n, FILE *stream); // 读取n-1字符到str中,最后一个位置自动补`\0`
fgets读取到换行符或n-1个字符后停止- 自动添加
\0终止符

4.3 格式化读写
int fprintf(FILE *stream, const char *format, ...); // 格式化写入到磁盘
将可变参数中的数据,按照编写的format格式写入到strem流(先缓存再刷新到磁盘)中。
stream:目标文件(如stdout、stderr或FILE*文件指针)format:格式化字符串(类似printf)...:可变参数- 返回值:成功时返回写入的字符数,失败返回负值。
+--------------------------+ 格式化转换 +-------------------+ 写入文件
| 变量 (age, score,add) | ------------> | 格式化后的字符串 | ------------> log.txt
+--------------------------+ +-------------------+

int fscanf(FILE *stream, const char *format, ...); // 格式化读取内存
从strem(文件流)中按照format的格式匹配数据,转换数据并存储到变量当中。
stream:源文件(如stdin或FILE*文件指针)format:格式化字符串(指定如何解析数据)...:可变参数(存储读取的数据)- 返回值:成功匹配的参数个数,失败或
EOF时返回EOF(-1)
+-------------------+ 解析 & 转换 +---------------------+
| 文件内容 (字符串) | ------------> | 变量 (age, score,add)|
+-------------------+ +---------------------+

//将格式化数据写入字符串str
int sprintf(char *str, const char *format, ...);
//从字符串str中读取格式化输入 变量...
int sscanf(const char *str, const char *format, ...);
4.4 二进制读写
size_t fread(void *ptr, size_t size, size_t nmemb, FILE *stream);
size_t fwrite(const void *ptr, size_t size, size_t nmemb, FILE *stream);
参数说明:
ptr:指向要读写的数据的指针size:单个元素字节数nmemb:读写元素数量stream: 文件指针
返回值:成功读写的元素个数
二进制写/读:stus是一个结构体数组可做首地址类似于数组名。


05. 文件随机读写
5.1 fseek()
功能:根据文件指针位置和偏移量来定位文件指针,跳转到指定位置
int fseek(FILE *stream, long offset, int origin);
- 参数:
stream:文件指针。offset:偏移量(字节数)。origin:基准位置,可选值:SEEK_SET:文件开头。SEEK_CUR:当前位置。SEEK_END:文件末尾。

5.2 ftell()
功能:返回当前文件指针相对于起始位置偏移量
long ftell(FILE *stream);
5.3 rewind()
功能:让文件指针回到文件起始位置
void rewind(FILE *stream);



















