前言
📫作者简介:小明Java问道之路,专注于研究计算机底层/Java/Liunx 内核,就职于大型金融公司后端高级工程师,擅长交易领域的高安全/可用/并发/性能的架构设计📫
🏆CSDN专家博主/Java领域优质创作者、阿里云专家/签约博主、InfoQ签约博主、华为云专家、51CTO专家🏆
🔥如果此文还不错的话,还请👍关注、点赞、收藏三连支持👍一下博主~
本文解读
一切都是文件,都可以用 “”打开open –> 读写write/read –> 关闭close” 模式来操作。输入/输出(I/O) 是指主存和外部设备(如磁盘,终端,网络)之间拷贝数据过程。
高级别IO有 C提供标准IO库 I/O函数 scanf 和 printf ,C++重载操作符<<和>>,Liunx系统使用内核提供的系统级I/O函数实现……大多数时候高级别I/O函数都运行良好,为什么我们还要学Unix I/O:了解Unix I/O将帮助你理解其他的系统概念。要深入理解其他概念,必须理解I/O。标准I/O库没有提供读取文件元数据的方式(如文件大小或文件创建时间)。
重点解读:
一、Unix I/O
一个Liunx文件就是一个m个字节的序列:B0 B1 ……B(m-1),所有I/O设备都被模型化为文件。而所有的输入和输出都被当做相应文件的读和写。这种将设备优雅地映射成文件,允许Unix内核引出一个简单,低级的应用接口。叫做Unix I/O。
打开文件:应用程序要求内核打开文件,内核返回一个小的非负整数,叫做描述符,它在后续对此文件的所有操作中标识这个文件。内核记录打开文件的所有信息,应用程序只需要记住描述符。
改变当前文件位置:对于每个打开的文件,内核保持一个文件位置k,初始为0。文件位置即是从文件开头起始的字节偏移量。应用程序通过执行 seek 操作,显式地设置文件位置 k 。
读写文件:一个读操作就是从文件拷贝n个字节到内存,然后将k增加到k+n。给定一个大小为m字节的文件,当k>=m时执行读操作会触发一个称 为 end-of-file(EOF)的条件。应用程序能检测到这个条件(或者说信号?),文件结尾并没有这样的符号。写操作就是从存储器拷贝n个字节到一个文件,从当前文件位置k开始,然后更新k。
关闭文件:当应用程序完成了文件的访问,通知内核关闭文件。作为响应内核释放文件打开时创建的数据结构。将描述符恢复到可用的描述符池中。无论一个进程因为何种原因被关闭,内核会关闭所有它打开的文件,并释放他们的内存资源。
二、打开和关闭文件
进程是通过调用 open函数来打开一个已存在的文件或者创建一个新文件的
三、读和写文件
调用read和write完成输入输出
四、读取文件元数据
应用程序能够通过调用stat和fstate函数,检索到关于文件的信息(有时也称为文件的元数据(metadata))
五、读取目录内容
应用程序可以用 readdir 系列函数读取目录的内容
六、共享文件
内核有三个相关的数据结构来表示打开的文件:
描述符表(descriptor table):每个进程都有它独立的描述符表。它的表项是由进程打开的文件描述符来索引的。每个打开的描述符表项指向文件表的一个表项。
文件表(file table):打开文件的集合是由一张文件表表示的。所有的进程共享这张表。每个文件表项的部分组成,包括当前的文件位置、引用计数(reference count)即当前指向该表项的描述符项数)、以及一个指向v-node表中对应表项的指针。关闭一个描述符会减少相应文件表表项中的引用计数。当引用计数变为0。内核会删除这个文件表表项。
v-node表:所有的进程共享这张表。每个表项包含stat结构的大多数信息。包括st_mode、st_size。
重定向标准输出之后的内核数据结构
七、标准I/O
ANSI C定义了一组高级输入输出函数,称为标准I/O库。这个库(libc)提供了,打开和关闭文件的函数(fopen和fclose)、读和写字节(fread和fwrite)、读和写字符串的函数(fgets和fputs)、以及复杂的格式化I/O函数 (scanf和printf)
我们该使用哪些I/O函数
总结
1、Linux提供了少量的基于Unix I/O模型的系统级函数,它们允许应用程序打开、关闭、读和写文
件提取文件的元数据,以及执行 I/O重定向。
2、Linux的读和写操作会出现不足值,应用程序必须能正确地预计和处理这种情况。
3、应用程序不应直接调用UnixI/O函数,而应该使用RIO包,RIO 包通过反复执行读写操作,直到传送完所有的请求数据,自动处理不足值。
4、Linux内核使用三个相关的数据结构来表示打开的文件。描述符表中的表项指向打开文件表中的表项,而打开文件表中的表项又指向 v-node 表中的表项。每个进程都有它自己单独的描述符表,而所有的进程共享同一个打开文件表和v-node表。理解这些结构的一般组成就能使我们清楚地理解文件共享和 I/O重定向。
5、标准 I/O库是基于Unix I/O实现的,并提供了一组强大的高级I/O例程。对于大多数应用程序而言,标准I/O更简单,是优于UnixI/O的选择。然而,因为对标准I/O和网络文件的一些相互不兼容的限制,UnixI/O比之标准I/O更该适用于网络应用程序。