【linux基础I/O(二)】文件系统讲解以及文件缓冲区的概念

简介: 【linux基础I/O(二)】文件系统讲解以及文件缓冲区的概念

1. 前言

对于文件来讲,有打开的在内存中

的文件,也有没有打开的在磁盘上

文件,上一篇文章讲解的是前者,本篇

文章将带大家了解后者!

本章重点:

本篇文章着重讲解在磁盘中的文件的
存储方式以及inode相关概念.在这之前
会解释C语言缓冲区的概念以及作用,
最后会带大家了解软硬链接如何创建,
软硬链接的区别,理解动静态库


2. 理解C语言的缓冲区

缓冲区的本质就是一段内存空间

那么为什么要有缓冲区?讲个例子

你在云南大学想要将一本书送给你在
北京邮电大学的好友,你会亲自将书带
过去给他然后再回云南吗?显然不可能
你会去楼下的顺丰快递将书籍让顺丰帮
你寄到北京区,你就代表一个用户,而书籍
就是你要发送给其他用户的数据,顺丰就
是这个缓冲区.很明显缓冲区有以下性质:

  • 顺丰拿到你的快递立刻发送(立刻刷新)
  • 等累计快递达到一定数量统一发送(行刷新)
  • 或者当快递站放满了再发送快递(满刷新)

行缓存的设备文件: 显示器(关心用户体验)
全缓存的设备文件: 磁盘文件(关心效率)

执行下面的代码时,不会立刻打印出信息:

printf("abcdef");
sleep(5);
return 0;

因为printf后没有\n刷新缓冲区,所以

信息不会立刻打印出来,当休眠五秒

后程序退出时才会进行刷新缓冲区!

函数fflush可以强制刷新缓冲区

除此之外,既然操作系统只认识文件描述符
fd,所以C语言的FILE结构体中一定封装了fd
,并且C语言的缓冲区实际上也是在FILE结构
体中维护的!也就是说直接使用系统调用去进
行输出工作是不会有缓冲区的概念的!


3. 对文件系统的初认识

对于已经在内存中打开的文件来说,它的

结构无非就是OS为它创建的struct file,

但是对于未打开的文件也就是存储在磁盘

上的文件,是怎样管理的呢?

看看关于磁盘结构的剖析图:

磁盘看似是一张盘面,实际上内部分为

很多个面,一个面对于一个磁头,这是正

视图的磁盘,再来看看俯视图的磁盘:

对于磁盘的每一个面来说,并不是所有
的区域都可以用来存储数据,可以把特
定的磁道中特定的扇区看作是一个小
数组,此小数组中存储文件的属性内容
一般而言一个扇区的大小是512字节

所以我们把把整个磁盘文件的管理
细拆分为对一个扇区的管理!!!


4. 扇区中的块组是如何工作的?

每个扇区是512字节的大小,每个分区会

划分不同的块组,将所有的块组管理好也

就将整个磁盘管理好来了!

块组的基本结构:

  • inode Table保存对应文件的属性.每一个inode块都有一个inode编号,也就是说一个文件,一个inode,一个inode编号
  • Block Bitmap是个位图,表示特定的块组是否被使用
  • inode Bitmap也是个位图,表示特定的inode是否被占用
  • Data Blocks存储此文件的内容
  • GDT是块组描述符,表征这个块组有多大,已被使用了多少,有多少个inode,还剩多少个等等.
  • SuperBlock保存着文件系统的属性信息,每个块组都会备份一份,里面有每一个块组的信息

从今往后,要在磁盘中找到一个文件只需: 找到inode编号->分区特定的块组->inode->属性->内容
那么问题是文件的inode是什么我怎么知道?是的,
OS都考虑好了,在文件的目录中,存放着文件名和此文件的inode对应的映射关系,可以通过文件名直接找到inode!!!


5. 理解软硬链接

我们看到,真正找到磁盘上文件的并不是文件名,而是inode。 其实在linux中可以让多个文件名对应于同一个inode,这就是硬链接的原理

使用指令: ln 创建硬链接

使用方法: ln 已存在的文件 要创建的硬链接

可以发现,在创建硬链接前,test.cpp的引用计数是1,而创建硬链接后计数变成了2,其实硬链接的本质就是给相同的文件取别名,硬链接没有自己的inode,它和原文件的inode相同!请看下面的图片验证:

使用指令: ln -s 创建软连接

使用方法: ln -s 已存在的文件 要创建的硬链接

可以发现,创建的软连接是独立的一个文件,它有自己的inode,并且此软连接指向原文件,软链接相当于Windows下的创建快捷方式一样,它可以将文件路径很复杂的文件创建一个软链接到当前目录,想要使用原文件时,只需要使用软链接即可!


6. 理解动静态库

  • 静态库(.a结尾): 程序在编译链接时就把库的代码链接到可执行程序
  • 动态库(.so结尾): 程序运行时才去链接动态库的代码,动态库的代码是被共享的

gcc/g++默认使用的动态链接的方式,若

想要变为静态链接,在编译时加上-static

如何写一个自己的库?

.h文件写声明,.c写实现,将.c文件

编译成.o文件后,再将所有的.o文件

通过指针ar打包成一个库,将这个库

和.h文件放在同一目录,别人就能用了

制作静态库指令:

ar -rc libhello.a mymath.o myprintf.o

制作动态库指令:

gcc -shared myadd.o myprintf.o -o libhello.so

当别人要使用你写的库时,需要在编译
时带上选项-l加上你的库名,就像后面
在学习线程库时要加上选项-lpthread
,它的意思就是要使用pthread线程库


7. 总结

Linux的基础IO部分已经全部讲解

完毕,下一章将进入进程信号的学习.

掌握文件的inode相关知识可以更好

的帮助我们理解文件在打开和关闭时

分别是怎样运作的!


🔎 下期预告:Linux信号 🔍


相关文章
|
3月前
|
存储 数据管理 Linux
区分Linux中.tar文件与.tar.gz文件的不同。
总之,".tar"文件提供了一种方便的文件整理方式,其归档但不压缩的特点适用于快速打包和解压,而".tar.gz"文件通过额外的压缩步骤,尽管处理时间更长,但可以减小文件尺寸,更适合于需要节约存储空间或进行文件传输的场景。用户在选择时应根据具体需求,考虑两种格式各自的优劣。
427 13
|
4月前
|
安全 Linux
Linux赋予文件000权限的恢复技巧
以上这些步骤就像是打开一扇锁住的门,步骤看似简单,但是背后却有着严格的逻辑和规则。切记,在任何时候,变更文件权限都要考虑安全性,不要无谓地放宽权限,那样可能
143 16
|
4月前
|
存储 Linux 数据处理
深入剖析Linux中一切即文件的哲学和重定向的机制
在计算机的奇妙世界中,Linux的这套哲学和机制减少了不同类型资源的处理方式,简化了抽象的概念,并蕴藏着强大的灵活性。就像变戏法一样,轻轻松松地在文件、程序与设备之间转换数据流,标准输入、输出、错误流就在指尖舞动,程序的交互和数据处理因此变得既高效又富有乐趣。
64 4
|
5月前
|
NoSQL Linux 编译器
GDB符号表概念和在Linux下获取符号表的方法
通过掌握这些关于GDB符号表的知识,你可以更好地管理和理解你的程序,希望这些知识可以帮助你更有效地进行调试工作。
215 16
|
4月前
|
Linux
linux文件重命名命令
本指南介绍Linux文件重命名方法,包括单文件操作的`mv`命令和批量处理的`rename`命令。`mv`可简单更改文件名并保留扩展名,如`mv old_file.txt new_name.txt`;`rename`支持正则表达式,适用于复杂批量操作,如`rename 's/2023/2024/' *.log`。提供实用技巧如大小写转换、数字序列处理等,并提醒覆盖风险与版本差异,建议使用`-n`参数预览效果。
|
4月前
|
存储 Linux Shell
Linux进程概念-详细版(二)
在Linux进程概念-详细版(一)中我们解释了什么是进程,以及进程的各种状态,已经对进程有了一定的认识,那么这篇文章将会继续补全上篇文章剩余没有说到的,进程优先级,环境变量,程序地址空间,进程地址空间,以及调度队列。
84 0
|
4月前
|
Linux 调度 C语言
Linux进程概念-详细版(一)
子进程与父进程代码共享,其子进程直接用父进程的代码,其自己本身无代码,所以子进程无法改动代码,平时所说的修改是修改的数据。为什么要创建子进程:为了让其父子进程执行不同的代码块。子进程的数据相对于父进程是会进行写时拷贝(COW)。
82 0
|
5月前
|
Linux
【Linux】 Linux文件I/O常见操作技巧
以上就是Linux文件I/O操作的一些技巧,接纳它们,让它们成为你在Linux世界中的得力伙伴,工作会变得轻松许多。不过记住,技巧的运用也需要根据实际情况灵活掌握,毕竟,最适合的才是最好的。
132 28
|
缓存 Ubuntu 网络协议
Linux系统编程之文件I/O函数的使用:介绍文件I/O函数的基本概念、用法和实现方式
Linux系统编程之文件I/O函数的使用:介绍文件I/O函数的基本概念、用法和实现方式
270 1
|
小程序 Linux
【编程小实验】利用Linux fork()与文件I/O:父进程与子进程协同实现高效cp命令(前半文件与后半文件并行复制)
这个小程序是在文件IO的基础上去结合父子进程的一个使用,利用父子进程相互独立的特点实现对数据不同的操作
247 2