| 标准IO | 文件IO |
概念 | 使用库函数实现,将内核提供的IO函数接口进行了再次封装,因为有缓冲区,所以效率比文件IO高 对文件进行操作,使用的是文件指针来进行 标准IO = 文件IO + 缓冲区 | 使用系统调用,内核提供的函数,每次进行IO操作,进程都会从用户空间向内核空间进行一次切换 文件IO直接进行系统调用,用文件描述符进行对文件操作 |
文件标识 | FILE结构体
- FILE结构体时stdio.h头文件中已经定义的一个关于文件操作的结构体类型
- 后期关于标准IO的文件相关的操作,只需基于该结构体对象即可
- 使用fopen函数成功打开一个文件后,就会返回该文件对应的FILE类型的地址
- FILE结构体的原型
struct _IO_FILE { char* _IO_buf_base; char* _IO_buf_end; int _fileno; } typedef struct _IO_FILE FILE;
- 特殊的文件指针: 当运行一个进程时,系统自动打开三个文件FILE指针,表示用于对终端文件的操作
-
- stdin:标准输入流指针
- stdout:标准输出流指针
- stderr:标准错误流指针
| 文件描述符
- 对于标准IO,对文件进行操作,使用的是文件指针来进行,其中文件指针结构体中,除了包含缓冲区的相关信息外,还提供一个整数用于进行系统调用,这个整数就是文件描述符
- 对于文件IO而言,由于直接进行系统调用,所以,依赖的就是文件描述符进行对文件操作
- 所谓文件描述符,是使用open函数后,打开的一个用于对指定文件进行操作的一个整数
- 一个进程中文件描述符的个数是有限的,默认为1024个[0--1023],可以通过ulimit -a查看
- 文件描述符的使用原则:最小未分配原则
- 当一个进程启动后,系统会默认打开三个文件描述符
- 0:stdin->_fileno -->标准输入文件描述符
- 1:stdout->_fileno -->标准输出文件描述符
- 2:stderr->_fileno -->标准出错文件描述符
|
打开文件 | fopen #include FILE *fopen(const char *pathname, const char *mode);
- 功能:以指定的形式打开一个指定的文件,并返回该文件的文件地址
- 参数1:要打开的文件路径,是一个字符串
- 参数2:文件的打开模式,也是一个字符串,必须以以下字母开头
- 返回值:成功返回打开文件的文件指针,失败返回NULL,并置位错误码
| open #include #include #include int open(const char *pathname, int flags); int open(const char *pathname, int flags, mode_t mode);
- 功能:打开或创建一个指定的文件
- 参数1:要打开的文件路径
- 参数2:打开标志
- 以下三个模式中必须选择一个:
- O_RDONLY(只读)
- O_WRONLY(只写)
- O_RDWR(读写).
- 下面常用的打开标志
- O_CREAT:创建,如果第二个参数中有该值,则第三个参数必须要写,如果没有,则第三个参数可以省略
- O_TRUNC:清空文件内容
- O_APPEND:追加形式打开
- O_EXCL:确保创建一个新文件,如果文件已经存在,则open函数报错,错误码为EEXIST
- O_NONBLOCK:以非阻塞的形式打开文件
- 多个标识位使用位或隔开:
|
关闭文件 | fclose #include int fclose(FILE *stream);
- 功能:关闭指定的文件,关闭前刷新该文件指针对应的缓冲区,并关闭底层的文件描述符
- 参数:文件指针,使用fopen函数返回的文件指针
- 返回值:成功返回0,失败返回EOF(-1), 并置位错误码
| close #include int close(int fd);
- 功能:释放一个文件描述符关联的文件,后期可以用于别的文件
- 参数:要释放的文件描述符
- 返回值:成功返回0,失败返回-1并置位错误码
|
单字符输入 | fgetc #include int fputc(int c, FILE *stream);
- 功能:将给定的字符,写入指定的文件中
- 参数1:要输出的字符
- 参数2:指定的文件指针
- 返回值:成功返回写入的字符的unsigned char数据,失败返回EOF
| |
单字符输出 | fputc #include int fputc(int c, FILE *stream);
- 功能:将给定的字符,写入指定的文件中
- 参数1:要输出的字符
- 参数2:指定的文件指针
- 返回值:成功返回写入的字符的unsigned char数据,失败返回EOF
| |
字符串读 | fgets #include char *fgets(char *s, int size, FILE *stream);
- 功能:从指定的文件中读取最多size-1个字符,到s字符数组中
- 参数1:字符串容器
- 参数2:读取的大小,最多读取size-1个字符,字符串的最后会加上一个结束标志'\0'
- 参数3:文件指针
- 返回值:成功返回读取的字符串起始地址,失败返回NULL
- 注意:在读取数据时,如果遇到'\n'会结束一次读取,并且将'\n'也放入字符串中,后面加个'\0'
| |
字符串写 | fputs #include int fputs(const char *s, FILE *stream);
- 功能:将指定的字符串写入到指定的文件中去
- 参数1:要写入的字符串起始地址
- 参数2:要写入的文件指针
- 返回值:成功返回输出的字符个数,失败返回EOF
| |
格式化读 | fscanf int fscanf(FILE *stream, const char *format, ...); 功能:从文件中按给定的格式读取一些数据
- 参数1:文件指针
- 参数2:格式串
- 参数3:不定参数,个数根据参数2中的格式控制符而定
- 返回值:成功返回读取数据的项数,参数2中格式控制符的个数,失败返回小于参数2中格式控制符的个数
| |
格式化写 | fprintf int fprintf(FILE *stream, const char *format, ...);
- 功能:向文件中输出一个格式串
- 参数1:文件指针
- 参数2:格式串
- 参数3:不定参数,个数根据参数2中的格式控制符而定
- 返回值:成功返回输出的字符个数,失败返回一个负数
| |
模块化读 | fread #include size_t fread(void *ptr, size_t size, size_t nmemb, FILE *stream);
- 功能:从文件中读取nmemb项数据,每一项大小为size,将数据放入ptr指向的起始地址中
- 参数1:读取数据的容器起始地址
- 参数2:每一项的大小
- 参数3:总的项数
- 参数4:文件指针
- 返回值:成功返回写入的项数,失败返回一个小于项数的值
- 注意:fread是不区分文件结束或者文件读取错误的,需要使用feof和ferror来进行区分
| read #include ssize_t read(int fd, void *buf, size_t count);
- 功能:向指定文件中写入数据,起始地址为buf,一共写入count给字节
- 参数1:要写入文件的文件描述符
- 参数2:要写入数据的起始地址
- 参数3:写入数据的大小
- 返回值:成功返回读取字符的个数,失败返回-1并置位错误码
|
模块化写 | fwrite size_t fwrite(const void *ptr, size_t size, size_t nmemb, FILE *stream);
- 功能:将ptr指向的内容,写入到文件中去
- 参数1:要写入内容的起始地址,void*表示能够写入任意类型的数据
- 参数2:每一项的大小
- 参数3:总项数
- 参数4:文件指针
- 返回值:成功返回写入的项数,失败返回一个小于项数的值
| write #include ssize_t write(int fd, const void *buf, size_t count);
- 功能:向指定的文件中写入数据,起始地址为buf,一共写入count个字节
- 参数1:要写入文件的文件描述符
- 参数2:要写入数据的起始地址
- 参数3:写入数据的大小
- 返回值:成功返回写入数据的个数,失败返回-1并置位错误码
|
光标控制 | fseek #include int fseek(FILE *stream, long offset, int whence);
- 功能:移动光标的位置
- 参数1:要移动光标的文件指针
- 参数2:偏移量
- >0:向后偏移
- =0:不偏移
- 参数3:偏移起始位置
- SEEK_SET:文件开头位置
- SEEK_CUR:光标当前位置
- SEEK_END:文件结尾位置
- 返回值:成功返回0,失败返回-1并置位错误码
| lseek #include #include off_t lseek(int fd, off_t offset, int whence);
- 功能:将文件描述符对应的文件光标进行偏移
- 参数1:文件描述符
- 参数2:偏移量,以字节为单位
- 参数3:起始位置
- SEEK_SET:从文件开头
- SEEK_CUR:文件当前位置
- SEEK_END:文件结尾位置
- 返回值:成功返回光标现在所在位置,失败返回-1并置位错误码 (等价于:fseek+ftell)
|
光标控制 | ftell long ftell(FILE *stream); 功能:返回光标现在所在位置到开头的总字节数 参数:文件指针 返回值:当前文件指针的光标到开头位置的字节总数 eg: fseek(fp, 0, SEEK_END); //定位在结尾 ftell(fp); //返回的结果就是文件的大小 | |
光标控制 | rewind void rewind(FILE *stream);
- 功能:将光标重新定位在开头,等价于fseek(fp, 0, SEEK_SET);
- 参数:文件指针
- 返回值:无
| |