今天正式进入应用层的学习,那么梦开始的地方就是文件I/O,接下来几天的时间都会围绕这部分内容展开,主要内容如下:
三连即可提高学习效率
🧑🏻作者简介:一个学嵌入式的年轻人
✨联系方式:2201891280(QQ)
📔源码地址:https://gitee.com/xingleigao/study_qianrushi
⏳全文大约阅读时间: 120min
文章目录
文件基础
标准I/O
介绍
流
流的缓冲类型
三个特殊流
打开和关闭流
打开文件
处理错误信息
关闭文件流
程序中能够打开的文件或流的个数有限制,如何测试?
流操作
字符的输入输出
行输入输出
对象的输入输出
刷新流和定位
刷新流
定位流
判断流是否出错和结束
格式化输出和输入
格式化输出
格式化输入
思考和练习
写在最后
文件基础
在Linux下,一切皆文件
概念: 一组相关数据的有序集合
文件类型:
常规文件 r
目录文件 d
字符设备文件 c(输入输出设备)
块设备文件 b(输入输出设备)
管道文件 p(进程通信)
套接字文件 s(网络编程)
符号链接文件 l(类似于快捷方式)
系统调用相关和库函数的关系
内核实现了硬件和软件的隔离。
标准I/O
介绍
标准I/O由ANSI C标准定义
主流操作系统上都实现了C库
标准I/O通过缓冲机制减少系统调用,实现更高的效率(比如我们熟知的printf就是行缓冲。如果不\n就可能出错之前输出不了)
流
FILE
标准IO用一个结构体类型来存放打开的文件的相关信息
标准I/O的所有操作都是围绕FILE来进行
流(stream)
FILE又被称为流(stream)
文本流/二进制流
windows和Linux文件的区别
Windows:
二进制流: 换行符: ‘\n’
文本流: 换行符 :‘\r’ ‘\n’
Linux
换行符 : ‘\n’
流的缓冲类型
全缓冲
当流的缓冲区无数据或无空间时才执行实际I/O操作
行缓冲(printf scnaf)
当在输入和输出中遇到换行符(‘\n’)时,进行I/O操作
当流和一个终端关联时,典型的行缓冲
无缓冲(ttl)
数据直接写入文件,流不进行缓冲
三个特殊流
错误流默认无缓冲,stdin和stdout是行缓冲。
可以用下面的代码看print的缓存大小:
#include <stdio.h> #include <stdlib.h> #define N 100 int main(int argc, const char *argv[]){ int i; char a = 'a'; if(argc != 2){ printf("Usage:%s Number\n",argv[0]); return 0; } for(i = 0; i < atoi(argv[1]);++i) printf("%c",a); while(1); return 0; }
打开和关闭流
打开文件
FILE *fopen (const char *path, const char *mode);
成功返回指针
关于mode函数
新建文件权限
fopen() 创建的文件访问权限是0666(rw-rw-rw-)
Linux系统中umask设定会影响文件的访问权限,其规则为(0666 & ~umask)
Root用户是 022 普通用户是002
其实就是0666-022
用户可以通过umask函数或者命令修改相关设定
相关示例代码在:/io/1.stand_io/2.open_close/2.fopen.c
处理错误信息
extern int errno; void perror(const char *s); char *strerror(int errno);
errno 存放错误号,由系统生成
perror先输出字符串s,再输出错误号对应的错误信息
strerror根据错误号返回对应的错误信息
相关示例代码在:/io/1.stand_io/2.open_close/2.perror.c
关闭文件流
int fclose(FILE *stream);
fclose()调用成功返回0,失败返回EOF,并设置errno
流关闭时自动刷新缓冲中的数据并释放缓冲区
当一个程序正常终止时,所有打开的流都会被关闭。
流一旦关闭后就不能执行任何操作
相关示例代码在:/io/1.stand_io/2.open_close/2.close.c
程序中能够打开的文件或流的个数有限制,如何测试?
思路:循环打开流,成功则计数器累加,直到出错为止
示例代码/io/1.stand_io/2.open_close/2.fopen_num.c
每个程序默认有三个打开表项,就是stdin、stdout、stderror三个文件
所以最多的就是1024-3 = 1021