文件系统实验(操作系统)

news2024/11/24 14:21:05

文件系统实验

【预备知识】

1.文件系统的文件类型

为了便于用户利用终端进行输入和输出,UNIX系统做了专门安排。UNIX系统自动为用户打开3个文件:标准输入、标准输出和标准错误输出文件,文件描述符分别为0、1、2,缺省时,这些文件是重定向到终端的。

LINUX系统问价有如下的分类

文件类型

S_IFREG

普通文件

S_IFDIR

目录文件

S_IFCHR

字符设备文件

S_IFBLK

块设备文件

S_IFIFO

有名管道文件

S_IFLNK

符号链接文件

S_IFSOCK

网络套接字文件

普通文件、目录文件、符号链接文件、有名管道文件、字符设备和块设备文件等。文件的分类主要由其I节点中的i_mode给出。为了能够检查每个文件的类型,Linux系统在sys/stat.h中定于了文件类型struct stat,并用宏定义来解决文件的类型,每个宏的参数就是结构stat中的st_mode的值。表1给出sys/stat.h中定义的文件类型的宏:

Linux系统在sys/stat.h中定义了文件类型struct stat,其定义如下:

1  

struct stat

{

dev_t st_dev; /*文件所在设备;主次设备号*/

ino_t st_into; /*inode*/

mode_t st_mode; /*protection  mode*/

nlink_t st_nlink; /*number of hard links*/

uid_t st_uid; /*user ID of owner*/

gid_t st_gid; /*group ID of ower*/

dev_t st_rdev; /*device type(if inode device)*/

off_t st_size; /*total size, in bytes*/

blksize_t st_blksize; /*blocksize for filesystem I/O*/

blkcnt_t st_blocks; /*number of blocks allocated*/

time_t st_atime; /*time of last access*/

time_t st_mtime; /*time of last modification*/

time_t st_ctime;   /*time of last change*/

}

2.文件系统的有关系统调用

#include <sys/types.h>

#include <sys/stat.h>

#include <unistd.h>

int stat(const char * file_name,struct stat * buf);

int fstat(int filedes,struct stat*buf);

int lsrant(const char * name,struct stat * buf);

这些函数返回有关指定文件的信息。使用这些命令,不需要对文件有任何权限,只需要对指定目录有检索权限。

stat()函数统计由文件名指定的文件信息,并填充到以steuct stat为结构的buf中;

lstat()函数与stat()函数功能一样,只是仅仅统计文件的符号链接时有所不同。

fstat()函数与stat()函数功能一样,只是仅仅统计被打开的文件的类型。

3.创建新文件creat()

LINUX系统把所有文件都看成无结构的字符流式的文件,如果特定的应用中使用了某种类型的数据结构,只能由程序员对数据增加相应的结构。这样使得UNIX对文件的接口变得特别简单。

创建一个新文件要使用如下的语句序列:

#include<sys/ types.h >

#include<sys/ stat.h >

#include<sys/ fcntl.h >

Int open(const char * pathname ,int oflg[,mode_t mode]);

返回值:如果正确创建,返回文件的描述符;否则返回-1。

pathname是要创建文件的路径名。创建文件时,文件只能以只写方式打开,mode用来规定该文件的拥有者,小组用户及其他用户的访问权限。要求用按位逻辑加对下列符号常量(这些符号常量定义在sys/stat.h中)进行所需的组合;

S_IRUSR /*文件拥有者的读权限位,即0400*/

S_IWUSR /*文件拥有者的写权限位,即0*200*/

S_IXUSR /*文件拥有者的执行权限位,即0100*/

S_IRGRP /*小组用户的读权限位,即0040*/

S_WGRP /*小组用户的写权限位,即0200*/

S_IXGRP /*小组用户的执行权限位,即0010*/

S_IROTH /*其他用户的读权限位,即0004*/

S_IWOTH/*其他用户的写权限位,即0002*/

S_IXOTH /*其他用户的执行权限位,即0001*/

3个有用的按位加组合定义如下:

S_IRWXU定义为(S_IRUSR|S_IWUSR|S_IXUSR)/*即0700*/

S_IRWXG定义为(S_IRGRP|S_IWGRP|S_IXGRP)/*即0070*/

S_IRWXO定义为(S_IROTH|S_IWOTH|S_IXOTH)/*即0007*/

创建文件时,若文件已经存在,只要执行进程对文件所在目录有执行权,并对该文件有写权,系统使原文件的长度置0,释放文件占用的磁盘块,同时保持原文件的mode不变。

4.删除文件unlink() 

一个文件可以有多个路径,也即一个inode可能链接多个文件的目录项。系统调用unlink()的作用就是删除指定的目录项。也即将inode中的链接计数nlink减1.若链接计数减1后为0,且无进程正在使用,立即删除该文件(即释放文件的目录项,inode和文件占用的磁盘块),此后,文件不再存在;若链接计数减1后为0,且有进程正在使用,则立即返回,等进程使用完后,再删除;若链接计数减1后不为0,则立即返回。

5.打开文件open()

打开文件使用和creat()相同的头文件序列;

#include<sys/ types.h >

#include<sys/ stat.h >

#include<sys/ fcntl.h >

Int open(const char * pathname ,int oflg[,mode_t mode]);

返回值:如果正确打开,返回文件的描述符;否则返回-1.

其中,参数pathname是待打开的文件路径名;参数oflg规定了打开文件方法;仅当打开的文件不存在,需创建时,才使用mode这个参数规定文件的拥有者、小组用户、其他用户对新文件的访问方式。参数oflg可能的取值为下列3个值之一;

O_RDONLY : 以只读方法打开;

O_WRONLY:以只写方法打开;

O_RDWR;以读写方法打开。

该系统调用还允许将oflg与下列标志值进行按位逻辑加,以扩充其功能;

O_APPEND;当为(O_WRONLY | O_APPEND)时,打开文件允许向文件尾追加写;否则为覆盖写,即从文件头写。

O_CREAT;当为(O_WRONLY | O_CREAT)时,若打开的文件不存在,则创建文件,且必须带有参数mode,以规定文件的拥有者、小组用户、其他用户对新文件的访问方式。

O_EXCL;当为(O_WRONLY | O_CREAT | EXCL)时,若打开的文件不存在,则创建文件,且必须带有参数mode,以规定文件的拥有者、小组用户、其他用户对新文件的访问方式。当打开的文件存在时,则出错。使用这个参数可用来检查文件是否已经存在。

O_TRUNC;当为(O_RDWR | O_TRUNC) 或(O_WRONLY | O_TRUNC)时,将文件的长度截成0,文件的属性不变。

O_SYNC:文件以同步方式打开。若文件以同步方式打开时,进程每次进行write()调用时,都立即修改文件,即进程等待write()调用完成后才能继续执行。

6.文件关闭close()

文件关闭的系统调用格式如下:

# include <unistd.h>

int close( int fd);

其中,fd为文件的文件描述符。

返回值:成功时为0,失败时为-1.

7.读文件read()和写文件write()

任何文件在读写之前,必须先打开。文件被成功打开时,返回文件的描述符。只要文件是用O_RDONLY或O_RDWR或O_WRONLY标志打开,就可以用read()或write()系统调用从文件中读或向文件中写若干字节。这两个系统调用可能使用的语句序列如下:

# include <unistd.h>

ssize_t read( int fd, void * buf, size_t nbytes);

ssize_t write( int fd, conts void * buf, size_t nbytes);

返回:正确是为0或读写的字节数;错误时为-1.

其中,fd为文件的描述符,buf为读出货写入文件数据的字节数组,第三个参数是要传送的字节个数。例如:

Internet fd,n,nread,nwrite;

char buf[size];

nread=read(fd,buf,n)

nwrite=write(fd,buf,n);

进行读时,nread为读函数执行完后返回的字节数。返回的字节数可以少于要求读的字节数。当文件为终端时,一般read只读到下一个换行符为止。通常要少于请求的字节数。当返回值为0时,表明文件结束。-1表明出现了错误。如果文件尺寸不是buf的整倍数,某次read命令将返回一个较小的数,这一数即为write命令写入的字节数;下一次调用read时,将返回0。

进程写时,返回值为实际写的字节数;如果返回值与实际写的字节数不相等时,则出现错误。

磁盘缓冲块尺寸为512字节或1024字节(可参看stdio.h中的定义)。

7.文件的随机存取lseek(int fd,long off,int sbase)

#include<unistd.h>

#include<sys/types.h>

Int lseek(int fd,long off,int sbase);

Sbase的可能取值对文件读写指针的影响如下:

SEEK_SET=0,文件的读写指针置为off;

SEEK_CUR=1,文件的读写指针置为off+当前文件的读写

编程实现例<一>

【任务】

利用表1给出的宏来检查给定文件的类型。

【程序】

#include <sys/types.h>

#include <sys/stat.h>

#include “unistd.h”

int main(int argc,char * argv[])

{

int I;

struct stat bf;

char * ptr;

for (i=1,i<argc;i++)

{

printf(“%s:”,argv[i]);

if (lstat(argv[i],&bf)<0)//统计符号链接本身的信息

{

printf(“lstat error”);

Continue;

}

If  ((S_IFMT & bf.st_mode)==S_IFREG)

     Ptr=“regular”;

/*else if ((S_IFMT&bf.st_mode)==S_IFDIR)

     Ptr=“directory”;

else if ((S_IFMT&bf.st_mode)==S_IFCHR)

     Ptr=“character special device”;

else if ((S_IFMT&bf.st_mode)==S_IFBLK)

     Ptr=“block special device”;

else if ((S_IFMT&bf.st_mode)==S_IFFIFO)

     Ptr=“pipe special file”;

     */

Else

Ptr=“****unknown file mode***”;

Printf(“%s:\n”,ptr);

  }

 Exit(0);

}
修改后代码:

【运行结果】

编程实现例<二>

【任务】

cat命令的简单实现,完成从键盘复制到终端显示器。

【程序】

# include <unistd.h>

# define SIZE 512

main()

{

char buf[SIZE];

int n;

while((n = read(0,buf,sise of buf))>0)

write(1,buf,n);

exit(0);

}

修改后代码:

【运行结果】

【分析】

编程实现例<三>

【任务】

open和create系统调用的使用。一个用C语言的复制文件的例子。

【程序】

#include <stdio.h>

#include <sys/types.h>

#defin PERM 0644   /*rw for owner,r for group and other*/

char * progname;

main(argc,argv)

int argc

char * argv[];

{

int f1,f2,n;

char buf[BUFSIZ];

progname = argv[0];

if (argc! = 3)

printf(“Usage:%s from to”,progname);

if(f1 = open(argv[1],0)==-1)

printf(“can’t open %s”, argv[1]);

if((f2=creat(argv[2],PERM)—1)

printf(“can’t creat %s”,argv[2]);

while((n=read(f1,buf,BUFSIZ))>0)

if (write(f2,buf,n)! =n)

printf(“write error”,(char  * )0);

close(f1);close(f2);

exit(0);

}

修改后代码:

【运行结果】

编程实现例<>

【任务】

请编写一个程序,采用随机读写文件的系统调用,从文件的某个位置开始对文件进行读或写。

【程序】

#include<unistd.h>

#include<sys/types.h>

Main(int argc,char * argv[])

{

If((fd=open(argv[1],O_RDONLY))==-1)

exit(1);

lseek(fd,184L,0);

where=lseek(fd,0L,1);

printf(“NOW new pointer value is %d.\n”,where);

while((where=read(fd,&cl,1==1)

{

printf(“ %c,”,cl);

}

Printf(“.\n”);

}
修改后代码:

【运行结果】

总结:

   在实验中,我利用代码模拟了文件系统的基本操作,包括文件的创建、打开、读写、关闭和删除等。通过深入使用系统调用,如open、read、write、close等,我得以深刻体验到Linux内核与文件系统之间的交互过程。这一过程中,我不仅了解到了这些基本操作在内核中的实现细节,还感受到了Linux系统对于文件管理的严谨性和高效性。在文件随机访问的实验环节,我使用lseek系统调用来移动文件指针,从而实现了对文件任意位置的读写操作。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1840288.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

分班查询,一键发布,老师们都在用的分班查询系统

老师们开学季马上又要到了&#xff0c;回想起了每年埋头苦干&#xff0c;对着一堆堆的学生名单&#xff0c;一个个手动分配班级&#xff0c;再一个个通知家长和学生的日子&#xff0c;那种手忙脚乱&#xff0c;生怕出错的紧张感&#xff0c;是不是还历历在目&#xff1f;每次分…

Instagram Reels API接口——高效获取用户主页Reels视频

一、引言 Instagram作为全球知名的社交媒体平台&#xff0c;近年来推出的Reels功能受到了广大用户的热烈欢迎。Reels以短视频的形式&#xff0c;让用户能够轻松创作和分享有趣、有创意的内容。为了帮助开发者、品牌和分析师更好地利用这一功能&#xff0c;我们推出了一款专注于…

从视频创意到传播策略 | 医药产品TVC新媒体传播方案

作为营销策划人&#xff0c;你一定在寻找能够激发创意灵感、拓展策划视野的实战案例。这份最新传播方案由Unithought精心打造&#xff0c;不仅是一份详尽的策划指南&#xff0c;更是一次深入患者心灵的品牌传播实践。 何策网&#xff0c;每日收录全网方案PPT &#xff01; 方…

手把手教你如何修复填补画图时间序列时出现的空白区域,Python向,Plotly库

填补画图时出现的空白区域&#xff0c;Python向&#xff0c;Plotly库 画图的烦恼美丽的plotly库首选安排时间序列的引索Index接下来我们安排plotly来画图继续修正图的格式 画图的烦恼 大家画时间序列的时候肯定遇到过画图没有软件里来的那么舒服&#xff0c;怎么画都会出现空白…

计算机顶级会议和顶级期刊

顶级会议 国际计算机设计会议&#xff08;ICCD&#xff09;&#xff1a;由国际电气与电子工程师协会&#xff08;IEEE&#xff09;主办&#xff0c;是计算机体系结构领域的国际顶级会议之一&#xff0c;已经成功举办四十余届。 NeurIPS&#xff1a;全称神经信息处理系统大会&a…

机械臂 CoppeliaSim Simulink联合仿真

实现机械臂在CoppeliaSim&#xff08;以前称为V-REP&#xff09;和Simulink上的联合仿真涉及多个步骤&#xff0c;包括环境设置、模型导入、通信配置、控制算法设计和测试调试。 前期准备 安装软件配置工作环境创建和配置CoppeliaSim场景 导入机械臂模型配置机械臂参数在Simuli…

goldfish loss:减少训练数据泄漏,提高大语言模型输出的多样性

LLMs&#xff08;大型语言模型&#xff09;能够记忆并重复它们的训练数据&#xff0c;这可能会带来隐私和版权风险。为了减轻记忆现象&#xff0c;论文作者引入了一种名为"goldfish loss"的微妙修改&#xff0c;在训练过程中&#xff0c;随机抽样的一部分标记被排除在…

阿里云ECS(CentOS/Alibaba Cloud Linux)安装最新 Docker 方法

最近&#xff08;6月份&#xff09;我发现 docker 官方无法正常访问&#xff0c;docker pull 命令也执行失败&#xff0c;用 TZ 也一样&#x1f614;。 以下步骤适用于 CentOS 7/8或Alibaba Cloud Linux 系统。 1. 更新系统包 首先&#xff0c;确保您的ECS实例系统软件包是最…

《Linux运维总结:基于ARM64架构CPU使用docker-compose一键离线部署alertmanager v0.27.0高可用集群》

总结&#xff1a;整理不易&#xff0c;如果对你有帮助&#xff0c;可否点赞关注一下&#xff1f; 更多详细内容请参考&#xff1a;《Linux运维篇&#xff1a;Linux系统运维指南》 一、部署背景 由于业务系统的特殊性&#xff0c;我们需要面对不同的客户部署业务系统&#xff0…

ansible 模块进阶及变量

yum 模块进阶 - name: install pkgs hosts: webservers tasks: - name: install web pkgs # 此任务通过yum安装三个包 yum: name: httpd,php,php-mysqlnd state: present # 根据功能等&#xff0c;可以将一系列软件放到一个组中&#xff0c;安装软件包组&#xff0c;将会把很…

代码随想录第28天|回溯算法

491. 非递减子序列 思路: 不可以排序, 否则会改变元素的顺序对收获的结果有要求, num.size() > 2, 且 num[i - 1] < num[i]需要进行去重, 不能使用排序后的方法去重每一层可用 unordered_set 去重组合问题, for 遍历需要标记起始位置 bug: 一定要先判断元素是否重复, …

进阶篇06——锁

概述 全局锁 表级锁 表锁 元数据锁 元数据锁是系统自动加的&#xff0c;不需要我们手动执行命令添加。 意向锁 意向锁和元数据锁一样&#xff0c;也是在加行锁的时候自动给表加上相应的意向锁&#xff0c;不需要我们手动添加。 行级锁 行锁 读锁和读锁兼容&#xff0c;写锁…

【决战欧洲杯巅峰】AI模型预测[走地数据]初步准备工作

数据准备 首先&#xff0c;我们需要收集一些与欧洲杯比赛相关的历史数据。这些数据可能包括球队的历史战绩、球员的能力评分、比赛场地信息、历史交锋记录等。这些数据可以从公开来源获取&#xff0c;并进行适当的预处理和清洗。 特征提取 接下来&#xff0c;我们需要从收集…

项目实施经理岗位的工作内容(合集)

项目实施经理岗位的工作内容1 职责&#xff1a; (1)负责协调软件团队对软件产品的研发工作(包括代码开发&#xff0c;测试&#xff0c;部署实施等); (2)引导和解析客户需求&#xff0c;根据产品特点及用户个性化需求制定解决方案&#xff0c;完成客户宣讲等售前技术支持工作; (…

【机器学习】第5章 朴素贝叶斯分类器

一、概念 1.贝叶斯定理&#xff1a; &#xff08;1&#xff09;就是“某个特征”属于“某种东西”的概率&#xff0c;公式就是最下面那个公式。 2.朴素贝叶斯算法概述 &#xff08;1&#xff09;是为数不多的基于概率论的分类算法&#xff0c;即通过考虑特征概率来预测分类。 …

时序预测 | KAN+Transformer时间序列预测(Python)

预测效果 基本描述 KANTransformer时间序列预测 KAN作为这两年最新提出的机制&#xff0c;目前很少人用&#xff0c;很适合作为时间序列预测的创新点&#xff0c;可以结合常规的网络加上个优化方法做创新。适合功率预测&#xff0c;负荷预测&#xff0c;流量预测&#xff0c;浓…

接口联调测试脚本优化

工作中&#xff0c;或者面试中&#xff0c;人家会问有没有什么优势&#xff1f; 你可以说我不光会写接口脚本&#xff0c;还能对接口脚本的结构进行了优化。 接口无非就是输入参数、发送请求、对响应结果进行比对&#xff0c;这些过程 都是一样的。如果不做一个通用的方法。1…

【Java并发编程之美 | 第一篇】并发编程线程基础

文章目录 1.并发编程线程基础1.1什么是线程和进程&#xff1f;1.2线程创建与运行1.2.1继承Thread类1.2.2实现Runnable接口1.2.3实现Callable接口&#xff08;与线程池搭配使用&#xff09;1.2.4小结 1.3线程常用方法1.3.1线程等待与通知1.3.2线程睡眠1.3.3让出CPU执行权1.3.4线…

【JS重点16】对象原型

目录 一&#xff1a;对象原型是什么 二&#xff1a;对象原型作用 三&#xff1a;constructor属性 四&#xff1a;如何赚钱 一&#xff1a;对象原型是什么 每个对象都有一个属性__proto__(称为原型对象),该属性是一个对象 __proto__是JS非标准属性在实例对象中&#xff0c;…

【leetcode37-51】二叉树

94. 二叉树的中序遍历 # Definition for a binary tree node. # class TreeNode: # def __init__(self, val0, leftNone, rightNone): # self.val val # self.left left # self.right right class Solution:def inorderTraversal(self, root: O…