【Linux】文件系统

您所在的位置:网站首页 linux修改分区文件系统内容 【Linux】文件系统

【Linux】文件系统

2023-06-03 02:08| 来源: 网络整理| 查看: 265

目录 打开的文件语言层文件操作系统层文件操作文件描述符文件描述符表struct file 文件对象文件描述符的分配重定向dup2缓冲区 自主封装文件接口 磁盘中的文件磁盘物理结构物理存储结构从OS看文件分区与分组目录文件增删查改直接间接索引 软硬链接软链接硬链接 动静态库设计静态库设计静态库库的加载位置无关码

文件主要是打开的文件即内存文件,和在磁盘中的文件

打开的文件 打开文件本质时加载文件属性到内存OS根据文件属性创建相关内核数据结构(struct file),对打开的文件进行管理文件操作就是进程与创建的文件对象之间的联系 在这里插入图片描述 语言层文件操作 fopen, fputs, fclose, fprintfsprintf, snprintf, 将字符串信息格式化到一个自定义的缓冲区里,n为缓冲区大小 snprintf ---> buffer ---> fputs, fwritefgets, 从指定文件流中按行读取放到缓冲区 系统层文件操作

open int open(const char *pathname, int flags); 打开已有文件 int open(const char *pathname, int flags, mode_t mode); 创建并打开 flags标志位参数采用位图结构,一个比特位表示一个标志位,则一个int类型可以同时传递32个标志位 int fd = open("log.txt", O_WRONLY | O_CREAT | O_TRUNC, 0666);

write ssize_t write(int fd, const void *buf, size_t count); 注意写入时考虑’ '\0','\0'是C语言的规定,不是文件的规定,会被解释成乱码,'\n'可以正常识别

read ssize_t read(int fd, void *buf, size_t count); ssize_t n = read(fd, buffer, sizeof(buffer) - 1); //整体读取,无法按行读取

文件描述符

在这里插入图片描述

文件描述符表

文件描述符(open的返回值 fd)本质上是数组下标

在这里插入图片描述

每个 struct file 文件对象都对应一个缓冲区所谓的 IO类 read, write 函数,本质上是拷贝函数,是对用户空间和内核空间数据进行来回拷贝缓冲区内同何时刷新到磁盘中指定位置,是由OS自主决定的 struct file 文件对象

Linux下一切皆文件,Linux视角看到的都是经描述后的 struct file 文件对象, 其包含文件属性、文件匹配的缓冲区、文件的操作方法。

文件描述符的分配

文件描述符表中最小的没有使用的数组元素分配给新文件,将新文件的文件对象的地址填入该位置

重定向

重定向:在上层不能感知的情况下,OS内部更改进程对应的文件描述符表中的特定下标位置的内容

./a.out > log.txt //默认重定向的是1号标准输出文件 ./a.out > log.txt 2>&1 //先重定向1,再将已重定向到 1 中的内容覆盖到 2 ./a.out 1>log.txt 2>err.txt //将1号重定向到log.txt,将2号重定向到err.txt,以此可分别收集输出和错误信息

dup2

int dup2(int oldfd, int newfd); dup2(fd, 1); //注意使用时两 fd 参数分别指代

缓冲区 语言层C库缓冲区刷新策略:无缓冲,行缓冲,全缓冲缓冲区旨在节省调用者的时间(系统调用也要花费时间),以提高效率缓冲区在 fopen 打开文件创建的 struct FILE 结构体中,是C库负责维护的 对于下面这段代码 fprintf(stdout, "hello fprintf\n"); //暂存缓冲区 const char * msg - "hello world\n"; write(1, msg, strlen(msg)); //直接写给OS fork(); ./a.out //这里是向显示器打印,为行缓冲策略,直接打印出"hello fprintf",同时write也直接写,fork前两串信息都刷新了./a.out > log.txt //输出重定向到 log.txt,其为普通文件,刷新策略变为全缓冲,write 是直接写,fork 之前write信息已经刷新,而 fprintf还在缓冲区,fork 创建子进程之后,因为进程结束会清空缓冲区,所以父子进程先结束一方会触发写时拷贝,刷新拷贝内容到 log.txt,后结束的一方再将原来的缓冲区内容刷新到 log.txt,所以最终现象是 fprintf 打印了两份,原因是因为发生了写时拷贝 自主封装文件接口

gitee入口 https://gitee.com/honortech/linux/tree/master/5_26-mystdio

 

磁盘中的文件 磁盘物理结构 磁盘:盘片,磁头,马达南北极表示0和1,向磁盘写入相当于磁化,N->S, (0->1),反之为删除,(加热会消磁,导致数据丢失) 物理存储结构 磁盘的基本单元:扇区(sector),512字节,or 4kb,一般磁盘所有扇区都是512字节同半径的所有扇区构成一个磁道(柱面)(cylinder)定位扇区:先由伴经定位所处磁道,再根据磁道上扇区编号定位扇区, 用磁头(head)编号来定位面,即确定是哦那个哪一个磁头读取,CHS定位法 从OS看文件 OS实际进行IO的基本单位是4kb,一个OS级别的文件块包含8个扇区可以将磁盘看作一个大数组,计算机常规通过起始地址+偏移量的方式进行访问OS是通过LAB逻辑块地址来进行块级别的访问的 分区与分组

一块磁盘会被分区成多个分区,每个分区都有自己独立的一套文件系统 下图是一个分区 在这里插入图片描述 分组中:

super block 文件系统的所有属性信息,包含文件系统的类型,所在区分组情况 super block在该区内每个分组都有备份,并且是统一更新的,防止某份损坏导致故障Group Descriptor Table 组表述符,保存所在组的属性信息inode 128字节,记录文件的所有属性,一个文件对应一个inode,同时记录了该文件的数据所在的数据块编号inode table 保存组内所有文件的inode numberData Blocks 保存文件内容,每个数据块有其对应的编号,inode 中会保存Data Blocks中其文件内容对应数据块的编号inode Bitmap 位图结构,记录inode table 中 inode 使用情况使用率,每个比特位表示一个 inode 是否空闲可用Block Bitmap 每个比特位表示一个数据块是否空闲可用 目录

一个目录是一个文件,有其对应的 inode,和其文件容对应的数据块 目录对应的数据块中保存的是在该目录下的文件的文件名和文件 inode number 的映射关系,文件名和 inode number 互为 key 值

文件增删查改 文件的删除是通过修改bitmap位图结构完成,将对应的 inode Bitmap 和 Block Bitmap 中对应比特位置为 0,inode number 不能跨分区使用,因为一个分区一套文件系统 直接间接索引

在这里插入图片描述

软硬链接 软链接

ln -s myfile.txt my-sort //my-sort 软链接到myfile

软链接是一个独立的文件,有自己的 inode number,和 inode 对应的文件属性和文件内容软链接的文件内容保存的是指向文件的路径应用:windows下的快捷方式 硬链接

ln myfile.txt my-hard //建立硬链接

硬链接与目标文件同用一个 inode number,同一个 inodeinode 中有一项引用计数 ref_cnt,记录了当前 inode 的硬链接数硬链接本质是建立了新文件名与目标文件 inode 的映射关系,只是更改了目录unlink my-hard//删除硬链接应用:当前目录 . ,上级目录 ..目录的硬链接数可推测该目录下有多少个子目录,子目录的..是当前目录的硬链接不能给目录建立硬链接,容易造成环路路径问题 动静态库

编译器的语法报错:编译器除命令行启动模式外,还会有其他自动化模式,可以不断进行语法检查 语法提醒动能:编译器会预先包含语言库头文件,编译器会将输入的内容不断在包含的头文件中进行搜索

设计静态库

ar -rc libmymath.a *.o //将所有 .o 文件打包成 mymath 静态库 gcc -o mytest main.c -L ./lib -l mymath -I ./include -static //指定使用当前目录下 lib 中第三方库进行静态链接

设计静态库

gcc -fPIC -c myadd.c //形成含与位置无关码的二进制 .o 文件 gcc -shared -o libmymath.so *.o //将 .o 文件打包成动态库

静态库链接原则是将二进制代码直接拷贝到可执行程序中 动态库链接是在运行是去相关路径中进行查找

三种配置动态库的方式:

1…环境变量 将第三方动态库路径追加到 LD_LIBRARY_PATH 环境变量中(修改环境变量仅在本次会话内有效)2…软链接 在默认库路径下创建第三方动态库的软链接3…配置文件 在 /etc/lib.so.conf.d路径下sudo touch一个.conf文件,将第三方动态库路径写入到该文件,再sudo ldconfig使配置文件起效 库的加载 静态库的加载 直接拷贝,占用内存,下载周期变长,占用网络资源,但是可执行程序独立性强,不依赖于源库动态库的加载 动态链接将可执行程序中的外部符号替换成库中该符号所对应方法的地址代码执行方法时,因为方法已经建立了映射,所以是直接再所处地址空间内跳转的多个进程调用同一份方法,该方法再内存中只会加载一份,其他程序调用方法也是在其地址空间内跳转,这就实现了库的共享 在这里插入图片描述 位置无关码

相对编址:动态库中的地址都是偏移量,默认从零开始 链接库时,首先会维护库,这时便确定的起始地址,调用某方法时,加载到内存,根据其偏移量在地址空间中对应与库的起始地址的相对位置建立映射



【本文地址】


今日新闻


推荐新闻


    CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3