LV.5 文件IO

1 标准IO介绍及缓冲区

1.1 标准IO介绍

  • Linux IO进程课程目的:学习编写linux应用程序(APP)
  • Linux文件的种类 :
    常规文件
    目录文件
    字符文件
    块文件
    链接文件(相当于windows快捷方式)
  • IO的概念
    I input 输入设备 比如键盘鼠标都是Input设备
    O output 输出设备 比如显示器
    优盘,网口,既是输入也是输出

1.1.1文件基础

概念:

一组相关数据的有序集合

文件类型:

  • 常规文件 r
  • 目录文件 d
  • 字符设备文件 c
  • 块设备文件 b :U盘 flash块存储
  • 管道文件 p
  • 套接字文件 s
  • 符号链接文件 l

1.1.2 系统调用和库函数

  • 系统调用就是操作系统提供的接口函数.
  • 如果我们把系统调用封装成库函数就可以起到隔离的作用,提供程序的可移植性。
  • printf就是库函数然后调用了系统调用才在显示器上显示字符。

1.1.3 标准I/O

标准I/O由ANSI C标准定义

主流操作系统上都实现了C库

标准I/O通过缓冲机制减少系统调用,实现更高的效率

1.1.3.1 标准I/O-流

FILE

标准IO用一个结构体类型来存放打开的文件的相关信息

标准I/O的所有操作都是围绕FILE来进行

流(stream)

FILE又被称为流(stream)

文本流/二进制流

1.1.3.2 标准I/O-文本流、二进制流

Windows

二进制流: 换行符 '\n'

文本流: 换行符 '\r' '\n'

Linux

换行符 '\n'

1.1.3.3 标准I/O -- 流的缓冲类型

全缓冲

当流的缓冲区无数据或无空间时 才执行实际I/O操作
行缓冲

当在输入和输出中遇到换行符 ('\n')时,进行I/O操作

当流和一个终端关联时,典型的行缓冲
无缓冲

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

1.1.3.4 三种标准IO

1.1.4 总结

  1. 流的缓冲类型
  2. stdin / stdout / stderr
  3. stdin/stdout 默认是行缓冲
  4. stderr没有缓冲
  5. 写代码显示缓冲区大小

1.2 缓冲区实验

buff.c 代码

程序正常结束会刷新缓冲区。

  • Sleep函数:是释放cpu给其他应用程序使用的库函数。使用的头文件是#include <unistd.h>
  • 查看头文件方法:man 2 函数 ,或者 man 3 函数
c 复制代码
man 3 sleep
  • 标准IO库中,全缓冲 的默认缓冲区大小通常定义为BUFSIZ(在<stdio.h>中),大多数系统下为4096字节,以提高磁盘IO效率‌。
  • 行缓冲(如终端设备)的默认大小通常与终端行长度相关(如1024字节)‌

2 文件的打开和关闭概念

打开就是占用资源

关闭就是释放资源

2.1 文件的打开

  • 文件的打开函数
c 复制代码
FILE *fopen (const char *path, const char *mode);

Path: 普通文件当前路径不需要加目录,其他要使用完整的路径
Mode:返回值:出错返回NULL,所以使用fopen函数必须判断是否为空

  • 文件打开的模式mode(非常重要)

  • 编译错误:

  1. error: 'errno' undeclared 表示errno变量没有定义
    解决方法:如果是系统变量用include 头文件,如果是你自己的,自己手动定义。
bash 复制代码
f_open.c:9:38: error: 'errno' undeclared (first use in this function)
         printf("fopen:%s\n",strerror(errno));  
  1. warning: implicit declaration of f unction 'strerror' 表示strerror函数隐示的声明
    解决方法:include 添加对应的头文件。
bash 复制代码
f_open.c:10:29: warning: implicit declaration of function 'strerror' [-Wimplicit-function-declaration]
         printf("fopen:%s\n",strerror(errno));
  • perror 库函数 头文件stdio.h
    strerror 库函数 头文件 errno.h string.h
    perror和strerror 功能:打印系统的错误描述(注意:是系统错误,不是你自己代码错误)
  1. perror自动读取全局变量errno的值,无需手动传入错误码;而strerror需通过参数指定错误码(如strerror(errno))
  2. perror将错误信息输出到标准错误输出(stderr),而非stdout;strerror仅返回错误描述字符串,需配合其他函数(如printf)输出到指定位置
  3. perror的调用格式为perror("自定义提示"),输出结果为"自定义提示: 系统错误描述";strerror直接返回系统错误描述字符串(如"Permission denied"),需用户自行拼接额外信息
c 复制代码
#include <stdio.h>
#include <string.h>
 #include <errno.h>

int main(int argc, char const *argv[])
{
    // FILE* fp = fopen("lala.txt","r");
    // FILE* fp = fopen("lala.txt","w");
    FILE* fp = fopen("lala.txt","a");
    if(!fp){
        perror("fopen");//fopen: No such file or directory
        printf("fopen:%s\n",strerror(errno));

    }else{
        printf("Open file succuss\n");
    }
}

2.2 文件的关闭

函数原型:int fclose(FILE *stream)

  • fclose()调用成功返回0,失败返回EOF(-1),并设置errno
  • 流关闭时自动刷新缓冲中的数据并释放缓冲区 ,比如:常规文件把缓冲区内容写入磁盘
  • 当一个程序正常终止时,所有打开的流都会被关闭
  • fclose()函数的入参stream必须保证为非空,否则出现段错误。
c 复制代码
 if(fclose(fp) == 0){
        printf("fclose file succuss\n");
 }else{
        perror("fclose");
 }  

3 标准IO的读写(字符、行)

3.1 读写单个字符

3.1.1 字符的输入(读单个字符):

c 复制代码
int  fgetc(FILE *stream);
int  getc(FILE *stream);   //宏
int  getchar(void);

成功时返回读取的字符;若到文件末尾或出错时返回EOF(-1),

getchar()等同于fgetc(stdin)

getc和fgetc区别是一个是宏一个是函数

注意事项:

  1. 函数返回值是int类型不是char类型,主要是为了扩展返回值的范围。
  2. tdin 也是FILE *的指针,是系统定义好的,指向的是标准输入(键盘输入)
  3. 打开文件后读取,是从文件开头开始读。读完一个后读写指针会后移。读写注意文件位置!
  4. 调用getchar会阻塞,等待你的键盘输入

3.1.2 字符的输出(写单个字符):

c 复制代码
int  fputc(int c, FILE *stream);
int  putc(int c, FILE *stream);
int  putchar(int c);

成功时返回写入的字符;出错时返回EOF

putchar©等同于fputc(c, stdout)

注意事项:

  1. 返回和输入参数都是int类型
  2. 遇到这种错误:Bad file descriptor, 很可能是文件打开的模式错误(只读模式去写,只写模式去读)

3.2 按行输入文件(读取整个行)

c 复制代码
char  *gets(char *s);  读取标准输入到缓冲区s
char *fgets(char *s, int size, FILE *stream);

成功时返回s,到文件末尾或出错时返回NULL

遇到'\n'或已输入size-1个字符时返回,总是包含'\0'

注意事项:

  1. gets函数已经被淘汰,因为会导致缓冲区溢出
  2. fgets 函数第二个参数,输入的数据超出size,size-1个字符会保存到缓冲区,最后添加'\0',如果输入数据少于size-1 后面会添加换行符。

3.3 按行输出文件(写整个行)

c 复制代码
int  puts(const char *s);
int fputs(const char *s,  FILE *stream);

成功时返回非负整数;出错时返回EOF

puts将缓冲区s中的字符串输出到stdout,并追加'\n'

fputs将缓冲区s中的字符串输出到stream,不追加 '\n'

相关推荐
电鱼智能的电小鱼8 小时前
基于电鱼 ARM 工控机的煤矿主控系统高可靠运行方案——让井下控制系统告别“死机与重启”
arm开发·人工智能·嵌入式硬件·深度学习·机器学习
sheepwjl8 小时前
《嵌入式硬件(十八):基于IMX6ULL的ADC操作》
单片机·嵌入式硬件·imx6ull·adc
2301_8059629310 小时前
AXF文件变量地址查找完全指南
stm32
BMS苦研者11 小时前
芯片选型避坑指南:如何根据需求快速筛选MCU
单片机·嵌入式硬件
国科安芯12 小时前
基于AS32A601型MCU芯片的屏幕驱动IC方案的技术研究
服务器·人工智能·单片机·嵌入式硬件·fpga开发
努力学习的小趴菜。13 小时前
基于STM32的智能天气时钟
stm32·单片机·嵌入式硬件
逆小舟15 小时前
【STM32】电动车报警系统
stm32·单片机·嵌入式硬件
小范馆15 小时前
STM32 解锁芯片的方法
stm32·单片机·嵌入式硬件
BreezeJuvenile15 小时前
外设模块学习(13)——HW-493激光发射模块(STM32实现)
stm32·单片机·学习·hw-493激光发射模块