百度360必应搜狗淘宝本站头条
当前位置:网站首页 > 技术分析 > 正文

深圳大学操作系统实验四文件系统 深圳大学wind数据库

liebian365 2024-10-22 15:35 3 浏览 0 评论

实验目的

了解Linux 文件命令行操作命令;

了解Linux ext3文件系统上的软硬链接;


实验内容

可以使用Linux或其它Unix类操作系统;

学习该操作系统提供的文件系统的命令行接口;

学习文件的软硬链接的使用;


实验环境

硬件:桌面PC

软件:Linux 或其他操作系统

实验步骤及说明

学习使用Linux文件系统提供的的ls 、touch、rm、cp、mv、mkdir等命令(希望尽量涵盖各种满足日常编程所需操作),了解EXT2文件系统。

操作部分(参考):

  1. 构建以下目录子树:(20%)

你的私有目录

a

b

c

d

e

f

g

软链接

硬链接

  1. 创建一个4KB左右的文本文件,其内容为重复出现的“Hello Operating system”。读入该文件的目录项内容,并解读出其对应的inode节点号;然后读出对应的inode内容,找到文件的第一个扇区,读入第一个盘块并查看其内容;(30%)
  2. 学习Linux文件系统中关于文件硬链接和软链接的概念和相关操作命令,创建软硬链接各一个,用tree命令、ls -l和ls -i命令查看和对比它们的不同;(10%)
  3. 创建一个1GB的大文件,读入全部数据到内存中并记录所花时间,然后进行第二次读入并记录时间。(20%)

要求:用/proc/meminfo查看内存中页缓存使用的变化,并解释两次读入速度差异的原因。

实验报告要求:

  1. 按学校统一格式
  2. 需要给出具体命令和自行编写的程序的源代码
  3. 程序的设计需要给出设计思路或流程框图
  4. 实验操作的截图需要有必要的说明文字

选做:

利用df命令查看并解读文件系统的信息,学习mount/unmount命令如何将光驱或U盘挂载到系统中,并体验windows盘符和linux无盘符概念的差异。

查看c语言提供的fopen/fclose/fread/fwrite函数和操作系统直接对应的open/close/read/write两套接口的差异,弄清楚字符模式和二进制流模式是哪一层面的概念。

思考文件读写指针(游标概念)属于文件的逻辑抽象管理数据还是属于磁盘文件管理数据?文件指针是否需要保存在磁盘上,如果在磁盘上应该如何存放?如果在内存中又如何存放?

实验结果

学习使用Linux文件系统提供的的ls 、touch、rm、cp、mv、mkdir等命令(希望尽量涵盖各种满足日常编程所需操作),了解EXT2文件系统。

网上查阅资料得知,ls命令是用来显示目标列表的,输出信息可以彩色高亮显示以区分不同类型的文件(图1-1)

图 1?1 ls指令解释

Touch命令用于创建新的空文件,并且它还可用于更改现有文件和目录的时间戳(最近访问和修改的日期和时间),其语法是touch [option] file_name(s)(图1-2)。

图 1?2 touch创建空文件

Rm命令常用来删除目录里面的一个或多个文件的目录,也用于删除目录下文件与子目录,查阅资料发现其有以下参数(图1-3),图1-4是我们删除的实例。

图 1?3 rm命令参数

图 1?4 rm删除实例

Cp指令用于复制文件或目录,如果指定两个以上的文件或目录,且最后目的地是一个已经存在的目录,他会把前面的所有文件或目录复制到指定目录中,如果目录不存在则报错,且他具有许多参数(图1-5)。

图 1?5 cp指令参数

Mv指令是move的缩写,他可以用来移动文件或将文件改名,具体格式是

mv [选项] 源文件或目录 目标文件或目录,具体参数如下(图1-6)。

图 1?6 mv指令参数

Mkdir命令常用来创建目录,如果目录名前面没有加任何路径名,则在当前目录下创建由dirname指定的目录,如果给出了一个已经存在的路径,则将会在目录下创建一个指定的目录。命令格式为mkdir [OPTION]... DIRECTORY...,具体参数如下(图1-7)。

图 1?7 mkdir指令参数

关于ext4文件系统:目前大部分linux操作系统使用的是ext4文件系统,block是ext4的最小储存单位,使用blkid可以查看文件系统类型,每一个block只能存储一个文件的数据(图1-8)。

图 1?8 block等基础知识

EXT3文件系统会把整个分区划分成各个block group,每个块组由superblock,block group,block bitmap,inode bitmap和group descriptor以及inode table、data block组成(图1-9)。

Superblock用于记录文件系统的inode/block总量、使用量、剩余量、大小、以及文件系统的格式和相关信息。

Block bitmap记录所有使用和未使用的block号码,删除文件时,我们需要先从block bitmap中找到对应的block号码,更新标志为未使用,然后释放block。

Inode bitmap,记录使用和未使用的inode号码。

Group descriptor,描述每个区段的开始和结束的block号码,说明每个区段分别介于那些block号码之间。

Inode table,记录该组的所有inode的合集,可以通过inode编号以inode table起始位置做偏移找到inode位置。

图 1?9 EXT4文件系统分区功能

我们可以使用dumpe2fs打印ext4分区的详细信息,也可以通过dd了解文件在磁盘中的内容。

构建以下目录子树:(20%)

你的私有目录

a

b

c

d

e

f

g

软链接

硬链接

查阅资料得知,mkdir用于创建目录,默认情况下,ln用于产生硬链接,产生硬链接后目录项中的inode节点相同,即一个inode节点对应两个不通的文件名,两个文件名指向同一个文件;软连接称为符号链接,软连接的两个文件目录项的inode不通,但是他们inode的数据块指向的是目标文件的路径名,删除目标文件会使链接无效,软连接用ln指令的-s参数实现。

我们根据题意创建目录结构,首先先不考虑e和f文件,因为他们是链接的,不需要创建,所以暂时如下图2-1所示。

图 2?1 创建没有链接的文件目录结构

接着我们创建链接(图2-2)。

图 2?2 创建硬链接和软连接

创建一个4KB左右的文本文件,其内容为重复出现的“Hello Operating system”。读入该文件的目录项内容,并解读出其对应的inode节点号;然后读出对应的inode内容,找到文件的第一个扇区,读入第一个盘块并查看其内容;

根据题目要求,我们首先创建一个helloOS.txt的文件,然后在里面写上重复的Hello Operating system(图3-1)。

图 3?1 重复hello

为了解读其节点号,我们查阅资料得知,需要使用df指令,df指令主要来检查文件系统的磁盘空间占用情况,并且-i是来查看inode的节点信息的(图3-2)。

图 3?2 df参数

根据当前路径以及所查阅的资料, 我们查询helloOS.txt挂载在哪个文件系统下,我们发现是挂载在sda1文件系统下(图3-3)。

图 3?3 df -l查看信息

接着我们根据sda1查看该文件系统的类型,使用df -T的参数(图3-4),发现类型为EXT4。

图 3?4 查看文件系统类型

接着我们根据1.9,使用dumpe2fs查看sda1的文件系统的详细信息(图3-5),可以看到如下详细信息:

Inode大小为256字节

每组块存放8192个inode

每个block占用4096字节大小

系统中block总数为20971008个

系统里面inode总数为524880个

每组块里存放了inode的block数目为512块

图 3?5 dumpe2fs 查看信息

做个简单的计算,根据上述信息,每个block占用4096个字节,而每个inode占用256字节,4096/256=16,也就是每个块有16个inode,而每组块有512个block有inode,16*512=8192,与上图中inodes per group=8192相吻合。

根据stat指令简介(图3-6),我们可以使用其查看当前文件inode信息,主要是inode号,可以看到inode号为3804467(图3-7)。

图 3?6 stat指令

图 3?7 helloOS的详细信息

首先计算组号,因为每组有8192个inode,且inode是从1开始计数的,所以(3804467-1)/8192=464(组),根据刚刚dumpe2fs指令的结果,我们可以看到3144271-3415760刚好等于511(图3-8)。

图 3?8 464组号相关信息

然后我们根据上述信息计算:

inode表里面的索引值=inode编号%组内inode数目=(3804467-1)%8192=3378。也就是3804467号的inode第464组里面的偏移3378号的inode是目标inode,

因为一个block占4096字节,每个block只能有4096/16=16个inode,所以计算组内盘块号=组内索引/每个盘块有多少个inode=3378/16=211。

该inode在组内291盘块上,对应的偏移也是3378%16=2。

所以最终inode字节位置为(inode表起始盘块+inode组内盘块号)*盘块大小+盘块内偏移*inode大小=(15204384+211)*4096+2*256=62,278,021,632(byte)。

然后我们通过hexdump工具查看inode的内容(图3-9),结合图3-9我们知道在4字节偏移处为inode大小,查看得知为392,与源文件大小392字节相等,所以证明我们找到了inode(图3-10)。

图 3?9 ext4的inode结构体

图 3?10 hexdump查看inode

查阅资料得知,我们的inode中显示block地址在60字节偏移处(图3-11),此时我们查找60字节偏移处,因为是小端存储,所以块地址为0x00a138ce=10565838(图3-12)。

图 3?11 inode结构体中block偏移

图 3?12 查看块地址

我们尝试使用dd指令读取文件内容块地址为10565838的内容,首先我们先使用debugfs指令检查helloOS.txt文件的所在块号,也是10565838号!说明我们的计算正确,然后使用dd指令输出到out.txt文件中(图3-14),其中if=输入文件;of=输出文件;bs=步长;count=扫描的数目;skip=跳过的块数,并且查看结果(图3-15),发现正是我们文件的内容!

图 3?13 debugfs检查块号

图 3?14 dd输出对应快内容

图 3?15 输出结果

学习Linux文件系统中关于文件硬链接和软链接的概念和相关操作命令,创建软硬链接各一个,用tree命令、ls -l和ls -i命令查看和对比它们的不同;

我们在demo4文件夹中创建soft_and_hard.txt并且对其添加hardlink.txt的硬链接以及softlink.txt的软连接(图4-1),然后通过tree查看链接情况,发现softlink已经软连接到了soft_and_hard上面(图4-2)。

图 4?1 创建文件以及添加软硬连接

图 4?2 tree

然后通过ls -l查看目录下文件信息,发现hard_and_soft的硬链接计数和hardlink计数是相等的,都等于2,根据硬链接的定义,他们都是指向同一个文件的,但是softlink的连接计数为1,也就是被系统当做单独的文件,因为他的inode只记录了原文件的目录,与源文件不同内容的(图4-3),通过ls -i也能验证上述结论,就是hardlink与soft_and_hard有相同的inode号,也就是3804470,而softlink的不同,为3804471(图4-4)。

图 4?3 ls -l

图 4?4 ls -i

创建一个1GB的大文件,读入全部数据到内存中并记录所花时间,然后进行第二次读入并记录时间。(20%)

要求:用/proc/meminfo查看内存中页缓存使用的变化,并解释两次读入速度差异的原因。

我们首先使用dd命令创建一个bigFile.txt的大文件,输入为/dev/sda1 输出为该文件,大小为1G(图5-1)。

图 5?1 dd创建1G大文件

然后我们编写一个bigfile.c的代码文件,主要思路就是先创建一个1G缓冲区,然后文件流打开并读取,开始计时,读取完毕就结束计时,然后再按照相同操作操作一次(图5-2)。

图 5?2 bigfile.c

然后我们打开编译后的bigfile开始测试,首先不读取任何文件(图5-3),然后查看/proc/meminfo信息,可以发现cached有164268KB(图5-4),然后我们继续运行,第一次扫描用时6.53秒,然后查看meminfo发现cached增加到了173372KB(图5-5),然后运行第二次,发现用时比之前快了许多,仅有4.70秒(图5-6)。

图 5?3 不读取

图 5?4 meminfo查看cached

图 5?5 读取一次

图 5?6 查看meminfo

图 5?7 读取第二次

根据上述数据,我们可以得出:由于meminfo的cached页面明显增多,说明第一次读取文件的时候有许多数据进入了cached,然后第二次读取的时候直接读取cached比第一次读取的时候读取磁盘会快很多,虽然不是全部文件都进了cached,但也是优化了1秒多,快了许多。

利用df命令查看并解读文件系统的信息,学习mount/unmount命令如何将光驱或U盘挂载到系统中,并体验windows盘符和linux无盘符概念的差异。

我们在linux系统中直接使用df命令,可以看到第一列为文件系统的名字,第二列指block块的数目总量,第三列是已被使用的block量,第四列是可用块数目,USE%是使用占比,Mounted on是指挂载在哪个目录下,以/dev/sda1为例,他是挂载在”/”目录下的(图6-1)。

图 6?1 df命令

根据df参数介绍(图6-2),我们使用df -HT来查看文件系统信息,可以看到相较于df指令,他把size变成了我们常用的KB/MB/GB来划分,并且给出了文件系统的类型和挂载目录(图6-2)。

图 6?2 df参数介绍

图 6?3 df -HT

接着我们关闭虚拟机,在虚拟机中挂载一个iso文件,图中挂载了一个centos的iso文件(图6-4)。

图 6?4 挂载iso文件

接着我们开机,可以看到光盘显示在桌面上了(图6-5)。

图 6?5 iso文件读入

查看df -h指令,我们可以看到iso文件挂载在了/dev/sr0(图6-6)。

图 6?6 iso文件挂载目录

然后由于使用mount指令,我们查阅资料后明白mount的参数使用(图6-7),然后根据这个挂载到/home/liujunnan-2017303010/demo4/cdiso中(图6-8),然后进入cdiso目录查看,发现挂载成功(图6-9)。

图 6?7 mount参数

图 6?8 挂载到cdiso目录中

图 6?9 cdiso目录下文件查看

我们尝试使用umount命令卸载./cdiso,然后进入iso目录查看(图6-10),发现不挂载进不去(图6-10)。

图 6?10 卸载后无法进入iso目录

Linux与windows相比挂载移动存储设备十分不同,windows系统里面对于移动存储设备或者虚拟存储器,系统会自动分配一个盘符作为根目录,我们直接根据盘符访问就可访问文件(图6-11),但是在linux里面需要挂载,因为linux认为阴间设备也是文件,他们有各自文件系统,必须统一文件系统才能访问,这个统一的过程叫做挂载。

图 6?11 windows挂载

查看c语言提供的fopen/fclose/fread/fwrite函数和操作系统直接对应的open/close/read/write两套接口的差异,弄清楚字符模式和二进制流模式是哪一层面的概念。

查阅资料得知:open/close/read/write是低级IO, 是系统调用函数,而fopen/fclose/fread/fwrite是高级IO,是标准库中的函数,后者是由前者实现的。

open() 打开一个文件并返回它的句柄如果失败,将返回一个小于0的值,原型是int open(const char *path, int access [, unsigned mode]); 参数path是要打开的文件名,access是打开的模式,mode是可选项。表示文件的属性,主要用于UNIX系统中,在DOS/WINDOWS这个参数没有意义。

close() 关闭一个句柄,原型是int close(int handle);如果成功返回0

read() 块读文件,原型是int read(int handle, void *buf, unsigned len);参数buf保存读出的数据,len是读取的字节。函数返回实际读出的字节。

write() 块写文件,原型是int write(int handle, void *buf, unsigned len);参数的含义同read(),返回实际写入的字节。

1.fopen的原型是:FILE *fopen(const char *filename,const char *mode),fopen实现三个功能

为使用而打开一个流

把一个文件和此流相连接

给此流返回一个FILR指针

参数filename指向要打开的文件名,mode表示打开状态的字符串

fclose()的功能就是关闭用fopen()打开的文件,其原型是:int fclose(FILE *fp);如果成功,返回0,失败返回EOF。

fread的功能是从流中读指定个数的字符,原型是size_t fread(void *ptr, size_t size, size_t n, FILE *stream);参数ptr是保存读取的数据,void*的指针可用任何类型的指针来替换,如char*、int *等等来替换;size是每块的字节数;n是读取的块数,如果成功,返回实际读取的块数(不是字节数),本函数一般用于二进制模式打开的文件中。

fwrite与fread对应,向流中写指定的数据,原型是size_t fwrite(const void *ptr, size_t size, size_t n, FILE *stream);参数ptr是要写入的数据指针,void*的指针可用任何类型的指针来替换,如char*、int *等等来替换;size是每块的字节数;n是要写的块数,如果成功,返回实际写入的块数(不是字节数),本函数一般用于二进制模式打开的文件中。

对于open与fopen区别:

open是系统调用,返回的是文件句柄,文件的句柄是文件在文件描述副表里的索引,fopen是ANSIC标准中的C语言库函数,返回的是一个指向文件结构的指针)(图7-1)。

fopen用户态下就有了缓存,它使用了FILE这个结构保存缓冲数据。在进行read和write的时候减少了用户态和内核态的切换。而open没有缓存,每次读操作都直接从文件系统中获取数据。在进行read和write的时候每次都需要进行内核态和用户态的切换。

一般用fopen打开普通文件,用open打开设备文件。

图 7?1 fopen

我们看看write / read 和 fwrite / fread 的接口(图7-2),read与write作为系统调用,只需要指定读取和写的字节数count即可,但是fwrite与fread需要提供size也就是单个元素的大小,这意味着write/read是二进制流模式,直接读取字节,字符流是fwrite/fread用户层面的,按照对象大小灵活访问数据。

图 7?2 接口

一个文件可以以文本模式或二进制模式打开,这两种的区别是:在文本模式中回车被当成一个字符'\n',而二进制模式认为它是两个字符0x0D, 0x0A;如果在文件中读到0x1B,文本模式会认为这是文件结束符,也就是二进制模型不会对文件进行处理,而文本方式会按一定的方式对数据作相应的转换。

根据上述分析,我们可以推测出,二进制流是系统的层面,不分析单个元素的单位大小,而字符流是用户层面的,用户根据操作系统的二进制数据解析出字符流,解析的时候发生在用户空间。

思考文件读写指针(游标概念)属于文件的逻辑抽象管理数据还是属于磁盘文件管理数据?文件指针是否需要保存在磁盘上,如果在磁盘上应该如何存放?如果在内存中又如何存放?

通过分析fopen我们可以知道,该函数返回一个FILE*类型的指针变量,也就是文件指针。

从概念上来看,文件指针属于逻辑抽象管理数据。

但是从应用上看,linux文件指针存在于PCB中,也就是内存,而不是磁盘中,每次打开新文件都会获得从头开始的文件指针。

如果文件指针保存在磁盘上,则他应该在inode、FAT表或者是block中某个特定的位置,因为文件指针是互斥变量,那么每个block都有指针的话,就不能实现并行。

如果文件指针在内存中,那么必须存放在PCB中,这也意味着多个进程可以以不同进度访问同一个文件,使得系统更加健壮,也让系统支持并行。

四、实验体会:(根据自己情况填写)

通过本次实验,我受益匪浅:

  1. 通过对linux文件系统的实验,我明白了ln用于链接文件的作用,并且明白了touch指令用于创建新文件,rm用于删除,cp用于拷贝,mv用于移动重命名,mkdir用于新建目录
  2. 明白了EXT2文件系统的基本结构,大部分linux系统都是用的EXT2文件系统,明白了inode的计算方法,明白了使用df查看磁盘空间以及文件系统类型,debugfs查看文件所属盘块,hexdumpfs查看二进制文件内容,dd查看对应盘块内容。
  3. 明白了cache对于读写文件的加速效果,以及cache存在的必要性。
  4. 明白了可以使用ls -I 和ls -l 查看链接情况,并且每个文件的inode根据软硬连接的不同情况不同。
  5. 明白了mount和umount的作用,以及挂载对于linux 的必要性和与windows系统的挂载区别。
  6. 明白了linux读写文件的两种不同形式,分别是二进制流形式和字符形式。



相关推荐

快递查询教程,批量查询物流,一键管理快递

作为商家,每天需要查询许许多多的快递单号,面对不同的快递公司,有没有简单一点的物流查询方法呢?小编的回答当然是有的,下面随小编一起来试试这个新技巧。需要哪些工具?安装一个快递批量查询高手快递单号怎么快...

一键自动查询所有快递的物流信息 支持圆通、韵达等多家快递

对于各位商家来说拥有一个好的快递软件,能够有效的提高自己的工作效率,在管理快递单号的时候都需要对单号进行表格整理,那怎么样能够快速的查询所有单号信息,并自动生成表格呢?1、其实方法很简单,我们不需要一...

快递查询单号查询,怎么查物流到哪了

输入单号怎么查快递到哪里去了呢?今天小编给大家分享一个新的技巧,它支持多家快递,一次能查询多个单号物流,还可对查询到的物流进行分析、筛选以及导出,下面一起来试试。需要哪些工具?安装一个快递批量查询高手...

3分钟查询物流,教你一键批量查询全部物流信息

很多朋友在问,如何在短时间内把单号的物流信息查询出来,查询完成后筛选已签收件、筛选未签收件,今天小编就分享一款物流查询神器,感兴趣的朋友接着往下看。第一步,运行【快递批量查询高手】在主界面中点击【添...

快递单号查询,一次性查询全部物流信息

现在各种快递的查询方式,各有各的好,各有各的劣,总的来说,还是有比较方便的。今天小编就给大家分享一个新的技巧,支持多家快递,一次能查询多个单号的物流,还能对查询到的物流进行分析、筛选以及导出,下面一起...

快递查询工具,批量查询多个快递快递单号的物流状态、签收时间

最近有朋友在问,怎么快速查询单号的物流信息呢?除了官网,还有没有更简单的方法呢?小编的回答当然是有的,下面一起来看看。需要哪些工具?安装一个快递批量查询高手多个京东的快递单号怎么快速查询?进入快递批量...

快递查询软件,自动识别查询快递单号查询方法

当你拥有多个快递单号的时候,该如何快速查询物流信息?比如单号没有快递公司时,又该如何自动识别再去查询呢?不知道如何操作的宝贝们,下面随小编一起来试试。需要哪些工具?安装一个快递批量查询高手快递单号若干...

教你怎样查询快递查询单号并保存物流信息

商家发货,快递揽收后,一般会直接手动复制到官网上一个个查询物流,那么久而久之,就会觉得查询变得特别繁琐,今天小编给大家分享一个新的技巧,下面一起来试试。教程之前,我们来预览一下用快递批量查询高手...

简单几步骤查询所有快递物流信息

在高峰期订单量大的时候,可能需要一双手当十双手去查询快递物流,但是由于逐一去查询,效率极低,追踪困难。那么今天小编给大家分享一个新的技巧,一次能查询多个快递单号的物流,下面一起来学习一下,希望能给大家...

物流单号查询,如何查询快递信息,按最后更新时间搜索需要的单号

最近有很多朋友在问,如何通过快递单号查询物流信息,并按最后更新时间搜索出需要的单号呢?下面随小编一起来试试吧。需要哪些工具?安装一个快递批量查询高手快递单号若干怎么快速查询?运行【快递批量查询高手】...

连续保存新单号功能解析,导入单号查询并自动识别批量查快递信息

快递查询已经成为我们日常生活中不可或缺的一部分。然而,面对海量的快递单号,如何高效、准确地查询每一个快递的物流信息,成为了许多人头疼的问题。幸运的是,随着科技的进步,一款名为“快递批量查询高手”的软件...

快递查询教程,快递单号查询,筛选更新量为1的单号

最近有很多朋友在问,怎么快速查询快递单号的物流,并筛选出更新量为1的单号呢?今天小编给大家分享一个新方法,一起来试试吧。需要哪些工具?安装一个快递批量查询高手多个快递单号怎么快速查询?运行【快递批量查...

掌握批量查询快递动态的技巧,一键查找无信息记录的两种方法解析

在快节奏的商业环境中,高效的物流查询是确保业务顺畅运行的关键。作为快递查询达人,我深知时间的宝贵,因此,今天我将向大家介绍一款强大的工具——快递批量查询高手软件。这款软件能够帮助你批量查询快递动态,一...

从复杂到简单的单号查询,一键清除单号中的符号并批量查快递信息

在繁忙的商务与日常生活中,快递查询已成为不可或缺的一环。然而,面对海量的单号,逐一查询不仅耗时费力,还容易出错。现在,有了快递批量查询高手软件,一切变得简单明了。只需一键,即可搞定单号查询,一键处理单...

物流单号查询,在哪里查询快递

如果在快递单号多的情况,你还在一个个复制粘贴到官网上手动查询,是一件非常麻烦的事情。于是乎今天小编给大家分享一个新的技巧,下面一起来试试。需要哪些工具?安装一个快递批量查询高手快递单号怎么快速查询?...

取消回复欢迎 发表评论: