IO知识点梳理

为什么要学习IO

目的:为了将数据存储以及对于文件的操作

文件:普通文件或者硬件设备(Linux下一切皆文件)

Linux下的7种文件属性:
1.普通文件 -
2.目录文件 d
3.符号链接文件(软链接) l
4.字符设备文件 c
5.块设备文件 b
6.管道文件 p
7.套接字文件 s

IO的分类

第一类:标准IO(高级磁盘IO)
第二类:文件IO(低级磁盘IO)

标准IO与文件IO的区别

标准IO:
1.ANSI(美国标准协会)联合ISO(国际化标准组织)所形成的一个C标准(属于C库,含有一系列输入输出函数),只要操作系统支持C库,就可以使用这一类标准IO提供的函数,可移植性较高
2.操作的文件一般是普通文件
3.属于高级磁盘IO,存在缓冲区,减少了用户态切换至内核态,最后又返回用户态这样的频繁操作,意味着减少了系统开销
4.通过文件流(FILE*)操作文件(打开文件时,系统会自动将该文件的信息定义结构体类型struct FILE 来进行存储,因此可以通过FILE *文件指针来操作文件)

文件IO:
1.POSIX(可移植操作系统接口)推出的对于支持POSIX标准的系统间可以操作文件的一系列函数,UNIX系统一般都会支持POSIX的标准,可移植性不高(只能应用于UNIX系统)
2.操作的文件可以是普通文件或者设备文件(硬件)
3.低级磁盘IO,没有缓冲区,每一次都是系统调用,都会存在用户空间和内核空间的频繁切换工作,好处就是可以直接对于设备进行读写操作
4.通过文件描述符(非负的数字)来操作文件

系统调用和缓冲机制

系统调用与缓冲机制

库函数和系统调用函数的关系:大多数库函数都是由系统调用函数封装起来的

标准IO

概念:文件被打开时,创建的结构体名为FILE的结构体指针,形象的成为“流”

分析:为啥称结构体指针为流?
–》因为标准IO存在缓冲区,所以每一次向缓冲区不断放入数据(每一次的放入数据:均是需要通过文件指针来进行读写指向的文件),存在三个特点:
1.有源头:APP
2.有目的:缓冲区
3.持续性:不断放入数据到缓冲区
–》一旦具备以上3个特点,就会形成流,所以通过文件指针操作文件可以理解为是通过操作流来操作文件

流的分类

文件被打开的时候,会默认具备3个流:
标准输入stdin–>0 对应键盘
标准输出stdout–>1 对应终端
标准出错stderr–>2 向终端打印,不带缓冲区(意味着每一次出错就会立即刷新缓冲区)

因此:当用户以后想要操作文件时,就需要先打开文件,此时会拥有一个文件流指针,以后通过该文件指针就可以操作文件。

缓冲机制

全缓冲

理解:缓冲区被放满,程序结束,强制刷新,会引起缓冲区的刷新

行缓冲

理解:缓冲区被放满,程序结束,强制刷新,遇到换行符,会引起缓冲区的刷新

不带缓冲

理解:不存在缓冲区的概念–》每一次读写都是直接输出:stderr

名词解释:

缓冲区被放满:
在这里插入图片描述

程序结束:
在这里插入图片描述

强制刷新:
在这里插入图片描述
在这里插入图片描述

操作文件

提供给用户来操作文件的方式有3种:
思考:不管是那种方式来操作文件,流程为:

打开文件

函数原型:FILE *fopen(const char *pathname, const char *mode);
参数1:需要打开文件的名字(可以包含路径,指针类型)
参数2:打开文件的方式(指针类型)
返回值:
       打开文件成功之后的文件流指针
       失败为NULL

在这里插入图片描述

代码如下:
在这里插入图片描述
在这里插入图片描述

注意:进行写操作时,若指定文件不存在,会自动创建新文件,但读操作不会

操作文件–》读写文件

3种方法。

关闭文件

在这里插入图片描述

因此打开文件和关闭文件在标准IO下都是使用同一个接口,只是在操作文件的方式上存在选择。

按照字符操作

函数名:fgetc   fputc
头文件:#include<stdio.h>

函数原型:int fgetc(FILE *stream);
功能:从指定的文件流中获取
参数:指定获取一个字符所处文件的文件流
返回值:
    成功返回获取到的字符值,
    读取到文件末尾返回EOF(-1),
    操作中失败返回负数(不包含-1)

函数原型:int fputc(int c,FIFE *stream);
功能:向指定的文件流中输出一个字符
参数:
    参数1:需要输出的指定字符(字符被称为单字节的整形)
    参数2:指定输出字符到的文件对应的文件流
返回值:
    成功返回刚写入的字符值
    失败返回EOF(-1)

案例1:实现对于指定一个文件读取,读取方式为按照字符操作,将读取完毕之后的结果显示在终端行。(自己实现命令cat文件名)

思路:
1.打开需要显示文件内容所在的文件
2.获取一个字符
3.输出一个字符
4.重复2.3直至文件末尾截止
5.关闭文件

代码如下:
在这里插入图片描述

按照行操作

标志:寻找’\n’

函数:fgets fputs

函数原型:char * fgets(char *s, int size, FILE *stream);

参数1:即将存储内存空间首地址
参数2:存储内容空间的大小(可以sizeof()测得)
参数3:指定的文件流
返回值:
    成功返回存储内容空间首地址
    失败返回NULL

思考:fgets什么时候会返回?
—>情况1:第一次遇到’\n’就会返回
情况2:该行会比较长,需要多次读取才能读完,所以位于读到’\n’之前的多次都是读取到size-1就返回。

案例–>实现wc -l测试问文件行数的功能
在这里插入图片描述

按照块操作

函数:fread fwrite

函数原型:size_t fread(void ptr,size_t size,size_t nmemb,FILE *stream)

参数1:存储读取一块内容之后的空间地址
参数2:块的大小-->建议给1
参数3:块的个数-->建议给sizeof()
参数4:要读取的文件对应的文件流
返回值:成功代表读取的块的个数,失败返回0

函数原型:size_t fwrite(const void *ptr,size_t size,size_t nmemb,FILE *stream);
参数1:需要写入的内容之后的空间地址
参数2:块的大小-->建议给1
参数3:块的个数-->建议给sizeof()
参数4:要写入的文件对应的文件流
返回值:成功代表写入的块的个数,失败返回0

案例:
保存学生信息:
在这里插入图片描述

读取学生信息到结构体空间:
在这里插入图片描述

文件流的定位:

理解:文件指针的指示位置

在这里插入图片描述

代码如下:
在这里插入图片描述

特性函数:

1.perror("string");
    作用:可以输出出错的原因
2.feof(FILE *stream);
    作用:判断文件是否抵达文件末尾(不管是文本文件还是二进制文件,都可以判断)
    返回值:
        抵达文件末尾,返回值为非零
        未抵达文件末尾,返回值为零

文件IO

操作文件IO的函数:
open close read write

打开文件

头文件:
    #include <sys/types.h>
    #include <sys/stat.h>
    #include <fcntl.h>

函数原型:
    int open(const char *pathname, int flags);
功能:打开指定的文件
参数:
    参数1:所需打开文件的名字(包含路径)
    参数2:打开文件的方式-->主标志 | 副标志
返回值:
    成功返回一个大于0的数字(文件描述符)
    失败返回-1(errno ie set..)

    int open(const char *pathname, int flags, mode_t mode);
功能:打开指定的文件
参数:
    参数1:所需打开文件的名字(包含路径)
    参数2:所需打开文件的名字(包含路径)
    参数3:打开文件的方式-->主标志 | 副标志
返回值:
    成功返回一个大于0的数字(文件描述符)
    失败返回-1(errno ie set...)

在这里插入图片描述

关闭文件

#include <unistd.h>

int close(int fd);
功能:关闭一个文件描述符
参数:打开文件成功之后的文件描述符

写文件

#include <unistd.h>

ssize_t write(int fd, const void *buf, size_t count);
功能:向指定的文件描述符的文件内写入内容
参数:
    参数1:打开文件之后的文件描述符
    参数2:所需写入的内容所在空间首地址
    参数3:需要写入的字节数
返回值:
    成功返回写入的字节数
    返回0代表没有写入任何内容
    返回-1代表出错(errno is set...)

读文件

#include <unistd.h>

ssize_t read(int fd, const void *buf, size_t count);
功能:从指定的文件描述符的文件内读取内容
参数:
    参数1:打开文件之后的文件描述符
    参数2:存储读取到结果的空间首地址
    参数3:可以读取的字节数-->sizeof测得
返回值:
    成功返回存储的字节数
    返回0代表读取完毕
    返回-1代表出错(errno is set...)

案例:对于同一个文件进行读写操作的代码如下 :
代码如下:
建议选用while循环~
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

文件IO中文件指示位置定位

在这里插入图片描述

空洞文件

在这里插入图片描述
在这里插入图片描述

代码如下:

在这里插入图片描述

操作目录

函数:opendir readdir closedir

打开目录

#include <sys/types.h>
#include <dirent.h>

DIR *opendir(const char *name);


#include <dirent.h>

struct dirent *readdir(DIR *dirp); 


#include <sys/types.h>

#include <dirent.h>

int closedir(DIR *dirp);

在这里插入图片描述

操作目录

在这里插入图片描述
在这里插入图片描述

关闭目录

在这里插入图片描述

测试文件属性

在这里插入图片描述

在这里插入图片描述

穿透函数:当测试的文件是软链接文件时,此时测得属性是属于软链接所指向的源文件的属性
非穿透函数:当测试的文件是软链接文件时,此时测得属性是软链接文件自身的属性。

在这里插入图片描述
在这里插入图片描述

制作静态库和动态库

什么是库?

在这里插入图片描述

库存在的意义?

在这里插入图片描述

静态库

理解:

在这里插入图片描述

如何创建静态库

在这里插入图片描述

动态库

理解:

在这里插入图片描述

如何创建动态库

在这里插入图片描述
在这里插入图片描述

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值