什么是 IO
在计算机操作系统中,所谓的I/O就是 输入(Input)和输出(Output),也可以理解为读(Read)和写(Write)
IO操作会涉及到用户空间和内核空间的转换,先理解以下规则:
- 内存空间分为用户空间和内核空间,也称为用户缓冲区和内核缓冲区;
- 用户的应用程序不能直接操作内核空间,需要将数据从内核空间拷贝到用户空间才能使用;
- 无论是read操作,还是write操作,都只能在内核空间里执行;
标准IO与系统IO
-
- 系统IO:不带缓冲机制,系统IO可以操作普通文件与驱动文件
- 标准IO:带缓冲机制,标准IO只可以操作普通文件。提供多种的格式的输入输出如(字符串、整形......)
-
- 标准IO使用链表管理返回值(FILE类型的指针)
- 而系统IO使用顺序表管理返回值(int类型的下标)
-
- 系统IO:由操作系统直接提供的接口函数
- 标准IO:由标准C库(第三方库)提供的接口函数(通过封装操作系统提供的系统IO,再给用户使用)
-
无论是标准IO还是系统IO都会提前在自身的管理结构中先后打开stdin,stdout,stderr
-
标准IO=系统IO+缓冲区

缓冲的作用与刷新条件
作用:在进行数据的读写的过程中,先不把数据直接写入或者读入设备中,而是写或者读入内存空间,当满足一定条件时候,将该空间的文件写入文件或设备中。这样可以减少操作系统调用驱动程序或文件的次数,提高读写的速度,和代码的效率。因为每一次系统调用的过程都是很浪费系统资源的。
刷新条件:
文件打开
标准IO
FILE *fopen(const char *filename, const char *mode)
参数 |
|
filename |
字符串,表示要打开的文件名称 |
mode |
字符串,表示文件的访问模式。 |
选项 |
|
r |
打开一个用于读取的文件。该文件必须存在。 |
w |
创建一个用于写入的空文件。如果文件名称与已存在的文件相同,则会删除已有文件的内容,文件被视为一个新的空文件。 |
a |
追加到一个文件。写操作向文件末尾追加数据。如果文件不存在,则创建文件。 |
r+ |
打开一个用于更新的文件,可读取也可写入。该文件必须存在。 |
w+ |
创建一个用于读写的空文件。如果文件名称与已存在的文件相同,则会删除已有文件的内容,文件被视为一个新的空文件。 |
a+ |
打开一个用于读取和追加的文件。 |
上述后+b |
以二进制的方式打开(不加则默认以文本形式打开) |
返回值 |
成功返回文件指针(FILE *) |
失败返回NULL |
系统IO
int open(const char * pathname, int flags);
int open(const char * pathname, int flags, mode_t mode);
头文件 |
#include<stdio.h> |
|
#include<fcntl.h>//在centos6.0中只要此头文件就可以 |
|
#include<sys/types.h> |
|
#include<stdio.h> |
#incldue<sys/stat.h> |
|
参数 |
|
pathname |
要打开或创建的目标文件。 |
flags |
打开文件时,可以传入多个参数选项,用下面的 |
一个或者多个常量进行“或”运算,构成falgs。 |
|
选项 |
|
O_RDONLY |
以只读方式打开文件 |
O_WRONLY |
以只写方式打开文件 |
O_RDWR |
以可读写方式打开文件。 上述三种旗标是互斥的, 也就是不可同时使用, 但可与下列的旗标利用OR |
O_CREAT |
若欲打开的文件不存在则自动建立该文件 |
O_EXCL |
如果O_CREAT 也被设置, 此指令会去检查文件是否存在。 文件若不存在则建立该文件, 否则将导致打开文件错误。 |
O_APPEND |
当读写文件时会从文件尾开始移动, 也就是所写入的数据会以附加的方式加入到文件后面. |
返回值 |
成功返回文件标识符(int) |
失败返回-1 |
数据获取
标准IO
共有三类获取方式,六个函数接口
1. 按字符获取
int fgetc(FILE *stream)
int getc(FILE *stream)
int getchar(void)
参数 |
|
stream |
这是指向 FILE 对象的指针,该 FILE 对象标识了要在上面执行操作的流。 |
返回值 |
|
成功 |
读取到的单个字符 |
失败 |
EOF(End of File) |
2. 按行获取
char *fgets(char *str, int n, FILE *stream)
char *gets(char *s)
参数 |
|
str |
这是指向一个字符数组的指针,该数组存储了要读取的字符串。 |
n |
这是要读取的最大字符数(包括最后的空字符)。通常是使用以 str 传递的数组长度。 |
stream |
这是指向 FILE 对象的指针,该 FILE 对象标识了要在上面执行操作的流。 |
返回值 |
|
成功 |
返回相同的 str 参数 |
失败/到达文件末尾/没有读取到任何字符 |
返回一个空指针 |
3. 按块获取
size_t fread(void *ptr, size_t size, size_t nmemb, FILE *stream)
参数 |
|
ptr |
这是指向带有最小尺寸 size*nmemb 字节的内存块的指针。 |
size |
这是要读取的每个元素的大小,以字节为单位。 |
nmemb |
这是元素的个数,每个元素的大小为 size 字节。 |
stream |
这是指向 FILE 对象的指针,该 FILE 对象标识了要在上面执行操作的流。 |
返回值 |
|
成功 |
以 size_t 对象返回,size_t 对象是一个整型数据类型。 |
失败/到达文件末尾 |
总数与 nmemb 参数不同 |
系统IO
ssize_t read(int fd, void * buf, size_t count);
参数 |
|
fd |
这是指向 FILE 对象的指针,该 FILE 对象标识了要在上面执行操作的流。 |
buf |
这是指向内存块的指针。 |
count |
这是元素的个数,每个元素的大小为 1 字节。 |
返回值 |
|
成功 |
返回实际读到的字节数量 |
到达文件末尾 |
返回字节数<=count |
失败 |
-1 |
数据写入
标准IO
一共三类写入方式,六种接口
1. 按字符写入
int fputc(int c,FILE *stream)
int putc(int c,FILE *stream)
int putchar(int c)
参数 |
|
c |
这是y要写入的字符。 |
stream |
这是指向 FILE 对象的指针,该 FILE 对象标识了要在上面执行操作的流。 |
2. 按行写入
char *fputs(const char *str, FILE *stream)
char *puts(const char *str)
参数 |
|
str |
这是要写入的字符串。 |
stream |
这是指向 FILE 对象的指针,该 FILE 对象标识了要在上面执行操作的流。 |
3. 按块写入
size_t fwrite(const void *ptr, size_t size, size_t nmemb, FILE *stream)
参数 |
|
ptr |
这是指向带有最小尺寸 size*nmemb 字节的内存块的指针。 |
size |
这是要读取的每个元素的大小,以字节为单位。 |
nmemb |
这是元素的个数,每个元素的大小为 size 字节。 |
stream |
这是指向 FILE 对象的指针,该 FILE 对象标识了要在上面执行操作的流。 |
返回值 |
|
成功 |
返回写入的数据块个数=nmemb |
失败/到达文件末尾 |
返回值 < nmemb |
系统IO
int write(int handle,void *buf,int len);
参数 |
|
handle |
这是要获取文件指针的文件标识符 |
buf |
这是要写入的内容。 |
len |
这是要写入文件的长度。 |
返回值 |
|
成功 |
返回写入的数据块个数=nmemb |
失败/到达文件末尾 |
返回值 < nmemb |
文件关闭
标准IO
int fclose(FILE *stream)
参数 |
|
stream |
这是指向 FILE 对象的指针,该 FILE 对象指定了要被关闭的流。 |
系统IO
int close(int fd)
返回值 |
|
成功 |
返回0 |
失败 |
返回-1,并设置errno |
文件光标
标准IO
int fseek(FILE *stream, long int offset, int whence)
参数 |
|
stream |
这是指向 FILE 对象的指针,该 FILE 对象指定了要被关闭的流。 |
offset |
这是相对 whence 的偏移量,以字节为单位。 |
whence |
这是表示开始添加偏移 offset 的位置。一般指定为下列常量之一 |
SEEK_SET |
文件的开头 |
SEEK_CUR |
文件指针的当前位置 |
SEEK_END |
文件的末尾 |
|
|
系统IO
off_t lseek(int fd, off_t offset, int whence);
头文件 |
|
|
#include <sys/types.h> |
|
#include <unistd.h> |
参数 |
|
fd |
这是文件描述符。。 |
offset |
这是相对 whence 的偏移量,以字节为单位。 |
whence |
这是表示开始添加偏移 offset 的位置。一般指定为下列常量之一 |
SEEK_SET |
文件的开头 |
SEEK_CUR |
文件指针的当前位置 |
SEEK_END |
文件的末尾 |
返回值 |
|
成功 |
返回从文件头部开始算起到当前读写位置的偏移量 |
失败 |
返回-1,并设置errno |
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· winform 绘制太阳,地球,月球 运作规律
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· AI与.NET技术实操系列(五):向量存储与相似性搜索在 .NET 中的实现
· 超详细:普通电脑也行Windows部署deepseek R1训练数据并当服务器共享给他人
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理