一、流的缓冲类型
全缓冲:当流的缓冲区无数据或无空间时才执行实际的I/O操作;
行缓冲:当在输入和输出中遇到‘\n’时,进行I/O操作。当流和终端关联时,典型的行缓冲;
无缓冲:数据直接写文件,流不进行缓冲。

二、linux的文件类型:

三、系统调用

四、FILE:又称为流,C库中定义的一个结构体,标准io的所有函数操作都是围绕这个结构体。打开一个文件就会创建一个流。流分为:文本流和二进制流。
linux不区分文本流和二进制流。window下文本流换行符‘\r\n’,二进制换行符‘\n’,linux下都是‘\n’。
五、标准io预定义了3个流,程序运行时会自动打开:0 stdin、1 stdout、2 stderr。
六、流的六种打开模式:FILE *fopen(const char *path, const char *mode);

七、使用fopen打开一个文件:
#include <stdio.h>
int main(int argc, char *argv[])
{
FILE *fp;
fp = fopen("test.txt", "r+"); // 读写方式,文件必须存在
if(NULL == fp)
{
perror("fopen");
return -1;
}
return 0;
}八、使用printf()输出字符串结尾加‘\n’和不加‘\n’的区别:
shell终端上输出采用的是行缓冲,所以只有遇到‘\n’或者缓冲区满的时候才会正真从缓冲区写入到stdout流在终端打印,不叫\n是不能马上看到输出结果的,是存到了stdout流的缓冲区。
九、fopen创建文件默认是0666(rw-rw-rw-)& ~umask,新创建的文件默认是可读可写不可执行权限,0644


十、系统处理错误信息:printf("fopen:%s\n", strerror(errno));

11、关闭流:int fclose(FILE *stream);

12、一个进程最大打开流个数:1021 + stdin + stdout + stderr = 1024
13、读写流的三种方式:

14、读流函数:
#include <stdio.h> int fgetc(FILE *stream); // 从指定流读一个字符 int getc(FILE *stream); int getchar(void); // 从标准io流读一个字符
若读到文件末尾会返回EOF -1

15、写流函数:
#include <stdio.h> int fputc(int c, FILE *stream); // int c:要写入的字符 int putc(int c, FILE *stream); int putchar(int c);
示例:打开一个文件写入26个字母

16、从流中读一行字符串:
#include <stdio.h> char *gets(char *s); // 不推荐使用,如果用户输入的数据超出存放字符串的缓冲器会造成缓冲区溢出 char *fgets(char *s, int size, FILE *stream); // 成功返回s,到文件末尾或出错返回NULL,遇到\n或已输入size-1个字符时返回, 末尾会自动添加\0
17、向流中写一行字符串:
#include <stdio.h> int puts(const char *s); // 遇到\0会在末尾追加一个换行符,只能向stdout流写入 int fput(const char *s, FILE *stram); // 遇到\0结束符不会追加换行符

18、向一个流写入、读出指定长度的数据,按对象(可以是字符串文本文件也可以是二进制的文件)读写:
#include <stdio.h> size_t fread(void *ptr, size_t size, size_t n FILE *fp);

读写流示例:

19、小结:各个流读写函数的对比:

20、真正执行读写流的三种时刻:
缓冲区满;
流关闭;
fflush()手动刷新流缓存区的内容到流文件;
4. 通常情况下,流操作会先看流缓冲区的数据是不是要读写的数据,如果不是才会正真的通过系统调用读写流。

强制刷新流示例:

21、流的定位函数:FILE流结构体中有个变量用来保存流当前的读写位置

往一个文件追加内容示例:

获取文件总长度示例:

22、判断流是否出错、是否到文件末尾:

23、格式化输出函数:

格式化输出内容到流示例:

- 本文作者: 龙兄嵌入式
- 本文链接: https://hexo.880755.xyz/1970/01/01/zblog/download/32.标准IO/