文件相关概念

简介: 文件相关概念

文件相关概念


1、linux文件结构

在 linux 中,内核会根据不同的设备类型,封装出对应的不同的文件类型,以便顶层的应用进程快速识别底层中的设备,主要分为以下几种:

image.png

内核通过文件描述符来进行区分和引用特定的文件


文件描述符

 文件描述符是一个简单的整数,它是一个索引值,并指向内核中每个进程打开文件的记录表。当顶层的应用进程需要对底层的设备进行操作时,需要通过内核将设备对应的文件打开,同时内核会将打开的文件封装成文件描述符返回给用户进程。如果应用进程需要对对应的文件进行读写操作时,就会将文件描述符作为参传递给内核函数,进行操作。

一般情况下,当启动一个进程时,内核会自动为这个进程打开三个文件


分别为:

  • 标准输入(键盘),对应的文件描述符为 0,即宏 stdin
  • 标准输出(屏幕),对应的文件描述符为 1,即宏 stdout
  • 标准出错处理(屏幕),对应的文件描述符为 2,即宏 stder

(如果后面进程需要操作新的设备或者文件,则需要通过内核提供的功能函数先打开文件并返回文件描述符,才能进行各种功能操作,而这个文件描述总是从 3 开始递增分配,一个进程最多只能打开 1024 个。)

其中,进程是一个操作主体,文件是一个电路。


示例一:

两个进程打开相同的文件,得到的是相同的文件描述符。

image.png

结果:

image.png

示例二:

一个进程打开两个不同的文件会得到两个不同的1文件描述符

image.png

结果:

image.png


2、系统调用

用户空间是应用程序启动后执行时所处的地址空间。

内核空间是操作系统及其服务执行时所处的地址空间。

image.png

在有些情况下,用户空间进程需要获得一定的系统服务(调用内核的函数),这时操作系统需要提供一组封装好的“特殊接口”,以便用户进程通过这组接口,进入内核空

间访问内核函数,这时程序运行空间需要从用户空间进入内核空间,处理完之后再返回用户空间。

系统调用的函数会用一组系统调用号来区别。


例子:

int syscall(int number, ...)
number 是需要的函数的系统调用号


3、功能函数库

在 linux 操作中,特别是输入输出操作中,直接使用系统调用的效率非常低。

主要是原因是:

1)系统开销大

因为在执行系统调用的时,Linux 必须从用户态转换到内核态,还要返回用户态。

2)硬件对底层系统调用一次所能读写的数据块做出的限制

所以需要功能函数库配合系统调用来使用,因此以下图示的效率比较低。

image.png

应用进程在调用系统调用之前,通过调用一组已经实现的用户编程接口程序,对数据及操作进行加工处理,再调用内核提供的系统调用,可以在某种程序上避免出现以上问题

image.png

这个用户编程接口即应用空间实的功能函数封装库,例如 libc 库中,就实现了输入输出操作中的 open,read,write 等常用的库函数。通过这些封装好的库函数,我们可以更加快速、便捷地使用内核提供的系统调用。


下面是write系统调用过程分析图:

image.png

过程分析:

  1. 当我们需要向文件写入的时候,调用write函数
  2. write函数是实现的用户编程接口程序,对数据及操作进行加工处理。
  3. 接着,write函数会调用内核提供的系统调用syscall(int number, …),指明一个系统调用号。
  4. 然后这个系统调用号会与sys_write函数绑定,调用相关的驱动代码
  5. 驱动代码会处理底层的磁盘扇区(也就是当前想要处理的文件)

image.png

这两条语句是一样的。


非标准功能函数库的缺点:

但是此功能函数库与系统的关系还是比较大,与系统库是直接绑定的,与这个操作系统相关,只是一个简单的关系转换,这段代码就只能在固定这个系统的里面跑,就不能在其他的系统里面跑,没有跨平台性,会出现系统不兼容的问题,迁移到其他的系统就不能跑起来了。

用的库越高层,就有更好的兼容性。


4、文件的IO操作

有两套大类的操作方式:

1)不带缓存的文件 IO 操作(系统 IO 操作) — 调用非标准库函数实现的 IO 操作

不带缓存的 IO 操作,是通过调用 open、read、write、close 等 libc 库函数间接调用系统调用来实现 IO 操作。因为它们位于 C 标准库的 I/O 缓冲区的底层,所以称为无缓冲 I/O(Unbuffered I/O)。

这种操作方式,可以高效完成文件输入输出。它以文件标识符(整型)作为文件唯一性的判断依据。但是由于这种操作不是 ASCI 标准的,与系统有关,所以移植有一定的问题。当然,效率也是有问题的。

常用的非标准库实现的 IO 操作,主要有以下函数:Open/create/Close/Read/write/Lseek/


2)带缓存的文件 IO 操作 — 通过标准的 LIBC 库实现 IO 操作

带缓存的 IO 操作是在不带缓存的基础之上封装了一层,维护了一个输入输出缓冲区,使之能跨 OS,成为 ASCI 标准,称为标准 IO 库。

由于缓冲区的存在,使得不用频繁地调用系统调用,减少系统的开销,但是响应速度不够及时。移植性较好。

c 库中,常用的 IO 操作函数有 fopen,fwrite,fread 等等。

目录
相关文章
|
6月前
|
Linux 编译器 Android开发
设备树覆盖:概念与术语
设备树覆盖:概念与术语
109 0
|
6月前
|
存储 安全 算法
Secureboot概念
Secureboot概念
200 0
|
存储 Java 数据库连接
串池的概念
串池的概念
|
PHP 开发者
文件包含的概念与作用|学习笔记
快速学习文件包含的概念与作用
文件包含的概念与作用|学习笔记
|
前端开发 开发者
路径概念 | 学习笔记
快速学习路径概念
路径概念 | 学习笔记
|
存储 弹性计算 资源调度
【k8s】概念、构成
文章目录 前言 一、概念
112 0
【k8s】概念、构成
|
开发框架 安全 .NET
初学C#需要掌握哪些概念
今天给大家带来刚整理好的初学C#需要掌握的概念。
|
Linux 测试技术
软件测试Linux面试题:简述Linux文件系统通过i节点把文件的逻辑结构和物理结构转换的工作过程
软件测试Linux面试题:简述Linux文件系统通过i节点把文件的逻辑结构和物理结构转换的工作过程
166 0
|
数据采集 负载均衡 搜索推荐
会计学包含的两种程序设计思想
会计学包含的两种程序设计思想
会计学包含的两种程序设计思想
|
自然语言处理 运维 负载均衡
PolarisMesh系列文章——概念系列(一)
北极星是腾讯开源的服务发现和治理中心,致力于解决分布式或者微服务架构中的服务可见、故障容错、流量控制和安全问题。虽然,业界已经有些组件可以解决其中一部分问题,但是缺少一个标准的、多语言的、框架无关的实现。
389 0