【从零开始的嵌入式生活】文件I/O1——标准I/O(1)

简介: 【从零开始的嵌入式生活】文件I/O1——标准I/O(1)

今天正式进入应用层的学习,那么梦开始的地方就是文件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)

数据直接写入文件,流不进行缓冲

三个特殊流

8c734f1e14d4b89194abdf89fb3f3ae.png

错误流默认无缓冲,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函数

df2b191893eae667c9dbff8f6535b51.png


新建文件权限

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


相关文章
嵌入式C++(十三)(下)
嵌入式C++(十三)(下)
107 0
嵌入式C++(十三)(下)
|
C++ 索引 容器
嵌入式C++(十一)
嵌入式C++(十一)
114 0
|
设计模式 算法 搜索推荐
嵌入式C++(十三)(上)
嵌入式C++(十三)(上)
107 0
|
算法 Linux
【从零开始的嵌入式生活】文件I/O1——标准I/O(2)
【从零开始的嵌入式生活】文件I/O1——标准I/O(2)
【从零开始的嵌入式生活】文件I/O1——标准I/O(2)
【从零开始的嵌入式生活】必备基础知识7——函数(1)
【从零开始的嵌入式生活】必备基础知识7——函数(1)
【从零开始的嵌入式生活】必备基础知识7——函数(1)
|
Serverless
【从零开始的嵌入式生活】必备基础知识7——函数(2)
【从零开始的嵌入式生活】必备基础知识7——函数(2)
【从零开始的嵌入式生活】必备基础知识7——函数(2)
|
机器学习/深度学习 算法 Linux
【从零开始的嵌入式生活】必备基础知识3——输入输出
【从零开始的嵌入式生活】必备基础知识3——输入输出
【从零开始的嵌入式生活】必备基础知识3——输入输出
|
存储 小程序 编译器
【从零开始的嵌入式生活】必备基础知识1——数据的表示和程序编译调试
【从零开始的嵌入式生活】必备基础知识1——数据的表示和程序编译调试
【从零开始的嵌入式生活】必备基础知识1——数据的表示和程序编译调试