1.引言

随着计算机技术的快速发展,在计算机操作系统中,如何优化任务处理效率成为一大难题。通过一个简单多用户文件系统设计,加深对文件系统的理解及内部实现。运用多线程的调度尽可能的优化其效率,解决实际问题。

1.1任务要求

B类:用java语言模仿“生产者——消费者”问题
1.通过Java语言中的wait()和notify()命令模拟操作系统中的P/V操作;
2.为每个生产者/消费者产生一个线程,设计正确的同步算法
3.每个生产者和消费者对有界缓冲区进行操作后,即时显示有界缓冲区的 当前全部内容、当前指针位置和生产者/消费者线程的自定义标识符。
4.生产者和消费者各有两个以上。
5.多个生产者或多个消费者之间须共享对缓冲区进行操作的函数代码。

C类:文件系统
设计一个多用户文件系统,理解文件系统的层次结构,完成基本的文件系统create、open、close、read/write等基本功能,并实现文件保护操作。实现以此为基础加入自己设计功能的小型文件系统 。

需要解决的问题:
1.如何让生产者在缓冲区满时不加数据。
2.如何让消费者在缓冲区空时不取数据。
3.如何使多个生产者或消费者线程的处理不发生冲突。
4.如何实现对文件系统的保护。
1.2选题
B类:用java语言模仿“生产者——消费者”问题;
C类:文件系统

当前发展概述

所谓多线程的并发运行,其实是指从宏观上看,各个线程轮流获得CPU的使用权,分别执行各自的任务。在运行池中,会有多个处于就绪状态的线程在等待CPU,JAVA虚拟机的一项任务就是负责线程的调度,线程调度是指按照特定机制为多个线程分配CPU的使用权。Java虚拟机采用抢占式调度模型,是指优先让可运行池中优先级高的线程占用CPU,如果可运行池中的线程优先级相同,那么就随机选择一个线程,使其占用CPU。
文件系统是操作系统用于明确存储设备或分区上的文件的方法和数据结构;即在存储设备上组织文件的方法。操作系统中负责管理和存储文件信息的软件机构称为文件管理系统,简称文件系统。文件系统由三部分组成:文件系统的接口,对对象操纵和管理的软件集合,对象及属性。从系统角度来看,文件系统是对文件存储设备的空间进行组织和分配,负责文件存储并对存入的文件进行保护和检索的系统。具体地说,它负责为用户建立文件,存入、读出、修改、转储文件,控制文件的存取,当用户不再使用时撤销文件等。

可行性分析

对于运用Java语言模仿“生产者——消费者”问题,以及在Java虚拟机上的线程调度问题,以前学习过Java基础语法,掌握了Java中wait(),notify()等线程处理的方法。
对于设计多用户文件系统问题,小文件的高度并发访问性能低。当前很多服务不仅需要大量的大文件访问,而且需要小文件的并发访问。文件系统在访问一个文件时需要多次读写和多次网络来回,因此对低延迟的要求难度较高,需要深入钻研。

选题意义

在Java虚拟机上,通过运用Java语言模仿“生产者——消费者”问题,可以进一步加深我们对多线程方面知识的理解。这不仅可以巩固以前java所学的知识,还能进一步打好有关线程知识的基础。
通过设计一个多用户的“文件系统”,从中我们能更深理解文件系统的层次结构和内部实现,并可以熟悉文件系统create、open、close、read/write等基本操作,实现文件保护的同时,运用操作系统的所学知识加入自己设计的操作系统,由此实现对文件系统的创新。

2.需求分析与设计

2.1 需求分析

“生产者消费者”问题是研究多线程程序时绕不开的经典问题之一,它描述是有一块缓冲区作为仓库,生产者可以将产品放入仓库,消费者则可以从仓库中取走产品。解决生产者/消费者问题的方法可分为两类:(1)采用某种机制保护生产者和消费者之间的同步;(2)在生产者和消费者之间建立一个管道。第一种方式有较高的效率,并且易于实现,代码的可控制性较好,属于常用的模式。第二种管道缓冲区不易控制,被传输数据对象不易于封装等,实用性不强。
同步问题核心在于:如何保证同一资源被多个线程并发访问时的完整性。常用的同步方法是采用信号或加锁机制,保证资源在任意时刻至多被一个线程访问。Java语言在多线程编程上实现了完全对象化,提供了对同步机制的良好支持。在Java中一共有五种方法支持同步,其中前四个是同步方法,一个是管道方法。
1.wait() / notify()方法
2.await() / signal()方法
3.BlockingQueue阻塞队列方法
4.Semaphore方法
5.PipedInputStream / PipedOutputStream
生产者和消费者在同一时间段内共用同一个存储空间,如下图所示,生产者向空间里存放数据,而消费者取用数据,如果不加以协调可能会出现以下情况:

存储空间已满,而生产者占用着它,消费者等着生产者让出空间从而去除产品,生产者等着消费者消费产品,从而向空间中添加产品。互相等待,从而发生死锁。
要实现多用户文件系统,首先要实现Login用户登录,必须登录成功才能进入文件系统进行相应操作,进入后,通过树状展示文件目录,右侧显示文件夹图标或这文件图标,选中节点鼠标右键弹出菜单,有新建目录,新建文件,删除文件,打开文件,修改文件,并分别实现其功能。

2.2系统框架和流程

“生产者”与”消费者”问题流程图:

文件系统流程图:

用户登录模块:

新建文件模块:

修改文件模块:

删除文件模块:

2.3 系统流程和模块描述
本系统为多用户的文件系统,因为是多用户使用,所以具备登录系统,注册用户的功能,各个用户之间的文件系统互不干扰,同时又要实现对文件增删改查的功能。采用二级目录,第一级为用户账号,第二级对应用户账号下的文件。
系统采用结构体存储用户,文件目录等内容。
系统大致为一个二级文件系统,可以实现以下几个功能::login(用户登录)、view(查看文件内容)、create(新建文件)、delete(删除文件)、modify(修改文件)、dir(列文件目录)。

用户登录模块:
首先,刚进入系统,还不会有文件系统,显示用户登录模块。系统分区后,系统初始化要完成文件系统的建立。验证用户的身份,输入用户名和密码,登录成功后会初始化当前用户文件系统中的信息。如果用户没有通过身份验证,则提示登录失败,退出系统。

创建文件模块:
在用户登录后才具有的功能,查找一个未使用的文件块用来存放用户的文件信息,构建一个文件系统的元素放入找到的文件块中。新建文件时要求输入文件名称,当文件名称不与已存在的文件目录中名称冲突时,同时文件不发生越界,则文件创建成功。

删除文件模块:
在文件目录中选中要删除的文件,若文件存在则继续判断文件是否被锁定。如果文件正使用处于锁定状态则删除失败。若处于非锁定状态,则删除成功。

查看文件模块:
首先要接受查看文件的名称,查询文件是否存在,如果不存在,则无法查看文件。若文件存在,则创建查看文件的结点并复制文件信息,即可查看到用户文件的数据部分,将数据显示到界面。

3.数据结构

文件系统数据结构:

typedef struct UFD       //存储文件信息
{char name[10];     //文件名int attribute;     //属性int length;         //长度int a[10];      //为文件本身分配10个空间int *p1;          //一级索引,100个空间int (*p2)[100];     //二级索引,100*100个空间struct UFD *next;
}UFD;
typedef struct DIR      //存储目录信息
{DIR* above;            //上一结点char name[10];int length;DIR *next;           //下一结点UFD *File_head;       //此目录下的文件指针DIR *Dir_head;       //此目录下目录链表指针
}DIR;
class  test         //定义管理用户目录的类
{DIR *now;          //当前目录UFD *Fhead;           //文件的头结点DIR *Dhead;         //根目录的目录链头结点char code[10];      //密码char name[10];      //用户名int length;            //用户空间大小int status;         //是否获得空间
public:void set_status(int);int dele_user();int dis_file();     //显示文件所占外存块号int dis_dir(DIR *d);//当前路径int get_length();char const *get_name();char const *get_code();int get_status();int set_user(char *,char *);//设置用户名与密码DIR *get_now();int dele_file(UFD *f);       //删除文件int dele_dir(DIR*);           //删除目录Test();                       //构造~test();                    //析构int goback();               //返回上级int dis_now();                //显示当前目录int new_file();int new_dir();int open_dir();int open_file();int first_dele_file();      //删除文件的前部分工作int first_dele_dir();       //删除目录的前部分工作int set_code();
};
class Cdisk{                    //用户类
public:Test user[5];        //用户个数最多为5char code[10];int dis_disk();int first_dele_user();int dele_user(int);int new_user();             //查看当前用户与外存空间使用情况,后创建新用户int set_code();              //设置新密码int login(char);             //登陆Cdisk();virtual~Cdisk();            //虚函数,析构
};

4.关键技术

Java实现生产者与消费者问题:
生产者消费者问题,描述一组生产者向一组消费者提供产品信息。它们会共享一个有界的缓冲区,生产者向其放入产品信息,消费者从中取出产品信息。只要当前缓冲区未满,生产者就可放入产品消息,只要缓冲区中存有数据,消费者便可提取。
应满足以下两个同步条件:
1.仅仅在有缓冲池中至少有一个缓冲区已存入消息后,消费者才从中提取消息,否则消费者必须要等待。
2.仅仅有缓冲池至少有一个缓冲区为空,生产者才能将消息放入缓冲区,否则生产者必须等待。
使用
1.创建生产者,负责生产产品信息

2.创建消费者,负责消费信息

3.消费者类

4.生产者类


5.核心代码

public class ProductiveConsumption {private int front=0; //队头private  int next=0; //队尾private  int bufferLength;    //缓冲区大小private String buffer[];   //缓冲区private int emptyNum;public ProductiveConsumption(int bufferLength){this.bufferLength=bufferLength;buffer=new String[bufferLength];emptyNum=bufferLength;}//生产public  synchronized  void produce(String data){System.out.println("生产前,空缓冲区数目-----------"+emptyNum);System.out.println("***生产者正在生产"+data);while(full()){System.out.println("*****缓冲池已满,生产等待");try{this.wait();}catch (InterruptedException e){e.printStackTrace();}}this.notify();buffer[next]=data;next=(next+1)%bufferLength;System.out.println("****生产者成功生产:"+data);emptyNum--;System.out.println("生产后,空缓冲区数目-----------"+emptyNum);}//消费public synchronized  void consum(){System.out.println("消费前,空缓冲区数目-----------"+emptyNum);while (empty()){System.out.println("*****缓冲池为空,消费等待");try{this.wait();} catch (InterruptedException e){e.printStackTrace();}}System.out.println("***消费者正在消费"+buffer[front]);this.notify();System.out.println("****消费者成功消费:"+buffer[front]);front=(front+1)%bufferLength;emptyNum++;System.out.println("消费后,空缓冲区数目-----------"+emptyNum);}//缓冲区是否已满public boolean full(){if(emptyNum==0){return  true;}return  false;}//缓冲区是否为空public boolean empty(){if(bufferLength==emptyNum){return true;}return false;}}

使用synchronized对存储加锁,然后用objec原生的wait()和notify()做同步。通过加锁,限制同一时刻只能有一个读或写。
Wait()方法:当缓冲区已满或空时,生产者/消费者线程就会停止自己的执行,放弃锁,使自己处于等待状态,让其他线程执行。
Notify()方法:但生产者/消费者向缓冲区放入/取出一个产品时,向其他等待的线程发出可执行的通知,同时放弃锁,使自己处于等待状态。
6.测试类

文件系统:
空闲空间管理采用位示图法,文件目录采用多级目录使用,采用索引节点结构。
功能模块
1.创建文件

p=new UFD;   //首先开辟一个新的文件结构体
在根目录链中检查判断文件是否重名
cout<<"请输入建立的文件名:";cin>>p->name;if(now==0)            //根目录下的文件链f=Fhead;else             //当前目录下的文件链f=now->File_head;while(f!=0)            //检查是否文件重名{if(!strcmp(p->name,f->name)){cout<<"此文件已存在!"<<endl;return 0;  //退出}f=f->next;}
若空间不足,则无法执行创建操作:
if(p->length>disk_empty)      //空间不足{cout<<"文件太大,空间不足,当前空间为:"<<disk_empty<<endl;delete p;return 0;}
若空间剩余,则通过位示图法为其分配空间:disk_empty=disk_empty-p->length;  //剩余空闲盘块//for(i=0;i<p->length&&i<10;i++)        //文件较小时,直接地址,文件数据盘块号for(j;j<10000;j++)               //位示图法if(disk_block[j]==0)        //空闲{p->a[i]=j;             //得到此空间disk_block[j]=1;        //标记为已分配出去j++;break;                  //跳出寻找,为文件分配下一空间}

2.删除文件

int test::first_dele_file()  //删除文件的前面工作
{char temp[10],a[5];cout<<"你要删除的文件名:"<<endl;cin>>temp;UFD *f=Fhead; //数据文件头指针UFD *above=0;if(now!=0)f=now->File_head; //当前目录下的数据文件while(f!=0){if(!strcmp(f->name,temp))break; //找到,跳出above=f; //标记第一个文件f=f->next;}if(f==0){cout<<"此文件不存在"<<endl;return 0;}cout<<"确定删除"<<f->name<<"文件吗?按0确定,其他键取消"<<endl;cin>>a;if(a[0]!='0'){cout<<"已取消删除文件。"<<endl;return 0;}disk_empty+=f->length; //回收此数据文件的空间大小if(now==0)  //根目录{if(f==Fhead)Fhead=Fhead->next;elseabove->next=f->next;}else{DIR *d=now;while(d!=0){d->length=f->length;d=d->above;}if(f==now->File_head)now->File_head=now->File_head->next;elseabove->next=f->next;}length-=f->length;this->dele_file(f);cout<<"删除成功"<<endl;return 1;
}int test::dele_file(UFD *f)    //具体实现删除文件
{int i=0,m;for(i=0;i<10&&i<f->length;i++)  //回收文件具体空间,重置空闲{m=f->a[i];disk_block[m]=0;}if(f->p1!=0) //回收一级索引{for(i=10;i<110&&i<f->length;i++){m=f->p1[i-10];disk_block[m]=0;}delete[](f->p1);}if(f->p2!=0)  //回收二级索引{for(i=110;i<f->length;i++){m=(f->p2)[(i-110)/100][(i-110)%100];disk_block[m]=0;}delete[](f->p2);delete f;}f=0;   //要删除的文件为空了return 1;
}

3.打开文件:

UFD *f=Fhead;   //文件头指针if(now!=0)f=now->File_head; //指向文件while(f!=0){if(!strcmp(f->name,n)){cout<<"文件打开成功"<<endl;return 1;}f=f->next;}cout<<"当前目录无此文件"<<endl;

4.显示当前目录:

int test::dis_now()  //显示当前目录
{DIR *d=Dhead;UFD *f=Fhead;if(now!=0){d=now->Dir_head;   //当前目录下的目录链f=now->File_head;}if(d==0&&f==0){cout<<"当前目录为空"<<endl;return 0;}cout<<"当前目录大小:";if(now==0)cout<<length;elsecout<<now->length;cout<<endl;if(d==0)cout<<"当前目录下没有目录"<<endl;else{cout<<"当前目录下包含如下目录:"<<endl;cout<<setw(14)<<"目录名称"<<setw(14)<<"目录大小"<<endl;while(d!=0){cout<<setw(14)<<d->name<<setw(14)<<d->length<<endl;d=d->next;}}if(f==0)cout<<"当前目录下没有文件"<<endl;else{cout<<"当前目录下包含如下文件:"<<endl;cout<<setw(14)<<"文件名称"<<setw(14)<<"文件大小"<<setw(14)<<"文件属性"<<endl;while(f!=0){cout<<setw(14)<<f->name<<setw(14)<<f->length<<setw(14)<<f->attribute<<endl;f=f->next;}}return 1;
}

5.运行结果

5.1 运行环境
Windows x64
CPU2.8GHZ,8GB内存
Dev c++5.11编译器,idea(java)
5.2 服务模式
5.3 运行结果
5.3.1 系统主界面
Java模拟生产者与消费者的系统界面

5.3.2 多用户文件系统
系统首页
登录模块:可选择管理员模式和用户登录

管理员模式:

可在管理员模式创建系统用户,删除用户,查看当前用户。
用户模式:

用户模式可创建文件,删除文件,创建目录,删除目录,打开目录,返回上一层目录,查看当前目录,修改密码,查看文件。
创建文件:

创建目录:

打开目录:

查看当前目录:

直接查看文件:

删除目录:

删除文件:

6.调试和改进

在文件系统设计中,为了减少检索文件访问的物理块的数量,文件系统把文件目录项中的文件名和其他管理信息分开,后者单独组成一定长度的数据结构,即为索引节点。把文件控制块的内容与索引节点分开,这样加快了目录检索速度,还便于实现文件共享,有利于系统的控制和管理。

7.心得和结论

7.1结论和体会

通过这次操作系统课程设计,进一步加深了我对文件属性,文件操作的认识,在文件系统的设计中,难点应该是文件目录的管理,其中文件控制块和索引节点结构起了重要作用。文件控制块中,包含了文件使用,文件管理等信息。在系统中查找文件时,根据文件名找到控制块,再通过控制块获取到文件信息。
在实现java模拟生产者与消费者问题上,使用synchronized对存储加锁,来实现同步机制,进一步理解wait()和notify的方法应用,只要java类拥有这两个办法,就可为任何对象实现同步机制。

7.2进一步改进方向

设计文件系统时,为了便于实现,对文件读写做了简化,在执行读写命令时,只修改读写的指针,并未真正进行读写操作,因此未来需要完善读写操作。还有要有文件保护措施,在每次打开文件时,应再次设置保护级别,便可有二级保护。

7.3 分析设计方案对系统安全的影响

在文件系统中,增加了用户和管理员的密码管理,通过密码的保护来实现多用户登录,多用户使用各自的控制块管理文件。
主要参考文献
[1]张尧学,宋虹,张高,《计算机操作系统教程》[M].清华大学出版社,2013.
[2] 汤小丹,梁红兵,哲凤屏,汤子瀛,《计算机操作系统》[M].西安电子科技大学出版社,2014.
[3]王育勤,等,《计算机操作系统》,北京交通大学出版社,2004
[4]倪光南. Linux影响软件界走向,成最热门话题
[5]倪光南. Linux影响软件界走向,成最热门话题

文件系统源代码cpp文件


#include<string.h>
#include<stdlib.h>
#include<iostream.h>
#include<iomanip.h>
#if _MSC_VER>1000
#pragma once
#endif  //_MSC_VER>1000extern int disk_block[10000];
extern int disk_empty;typedef struct PCB        //存储文件信息
{char name[10];         //文件名int attribute;          //属性int length;                  //长度int a[10];                //为文件本身分配10个空间int *p1;                      //一级索引,100个空间int (*p2)[100];                 //二级索引,100*100个空间struct PCB *next;
}PCB;typedef struct DIR     //存储目录信息
{char name[20];int length;DIR* above;            //上一结点DIR *next;            //下一结点PCB *File_head;       //此目录下的文件指针DIR *Dir_head;       //此目录下目录链表指针
}DIR;class test             //定义管理用户目录的类
{DIR *now;          //当前目录PCB *Fhead;           //文件的头结点DIR *Dhead;         //根目录的目录链头结点char code[10];      //密码char name[10];      //用户名int length;            //用户空间大小int status;         //是否获得空间public:void set_status(int);int dele_user();int dis_file();     //显示文件所占外存块号int dis_dir(DIR *d);//当前路径int get_length();char const *get_name();char const *get_code();int get_status();int set_user(char *,char *);//设置用户名与密码DIR *get_now();int dele_file(PCB *f);       //删除文件int dele_dir(DIR*);           //删除目录test();                       //构造~test();                    //析构int goback();               //返回上级int dis_now();                //显示当前目录int createfile();int new_dir();int open_dir();int open_file();int first_dele_file();        //删除文件的前部分工作int first_dele_dir();       //删除目录的前部分工作int set_code();
};class Cdisk{                  //用户类
public:test user[3];          //用户个数 char code[10];int dis_disk();int first_dele_user();int dele_user(int);int createuser();                //查看当前用户与外存空间使用情况,后创建新用户int set_code();              //设置新密码int login(char);             //登录 Cdisk();virtual~Cdisk();           //虚函数,析构
};int disk_block[10000];
int disk_empty;Cdisk::Cdisk()       //管理磁盘的类,构造函数
{int i=0;char code[10]="123456";for(i=0;i<10000;i++)      //初始化所有磁盘块为空闲disk_block[i]=0;//this->user[0].set_user("student","123");//默认一个用户disk_empty=10000;cout.setf(ios::left);  //设置输出方式
}Cdisk::~Cdisk()        //析构
{}int Cdisk::dele_user(int i)        //Cdisk类dele_user的构造
{test C;C=user[i];user[i].dele_user();     //调用Cuse类的成员函数 int dele_user()return 1;
}int Cdisk::dis_disk()      //检查磁盘信息
{int i=0;cout<<setw(14)<<"用户名"<<setw(14)<<"占用空间大小"<<endl;for(i=0;i<3;i++)if(user[i].get_status()==1)     //存在的用户的信息cout<<setw(14)<<user[i].get_name()<<setw(14)<<user[i].get_length()<<endl;cout<<"已用空间:"<<10000-disk_empty<<endl<<"剩余空间:"<<disk_empty<<endl;return 1;
}int Cdisk::login(char b)       //登录
{char n[10],c[10];int i;if(b=='1'){cout<<"用户:管理员  密码:默认\n"<<endl;system("pause");return 1;}else{if(!user[0].get_status()) //当前不存在用户{i=0;cout<<"未注册用户,请注册用户!"<<endl;user[i].set_status(1);        //为新用户分配权利cout<<"请输入用户名:"<<endl;cin>>n;cout<<"请输入密码:"<<endl;cin>>c;user[i].set_user(n,c);     //调用Cuse的成员函数,传递用户名与密码cout<<"创建用户成功!"<<endl;return i;}else{cout<<"用户名:";cin>>n;cout<<"密码:";cin>>c;cout<<endl;for(i=0;i<3;i++)    //查找是否存在此用户{if(user[i].get_status())        //存在方比较if(!strcmp(n,user[i].get_name()))    //相等时为0,此判断为匹配if(!strcmp(c,user[i].get_code()))      //密码匹配{cout<<"登录成功!"<<endl;cout<<"欢迎"<<user[i].get_name()<<"登录"<<endl;return i;}else{cout<<"密码错误"<<endl;return -1;}}cout<<"此用户不存在!"<<endl;return -1;}}
}int Cdisk::set_code()      //设置新密码
{char temp1[10],temp2[10];cout<<"请输入原密码"<<endl;cin>>temp1;if(strcmp(temp1,code))        //无疑是针对当前用户进行操作,故直接code{cout<<"原密码错误!"<<endl;return 0;}while(1){cout<<"请输入新密码:"<<endl;cin>>temp1;cout<<"请再次输入新密码:"<<endl;cin>>temp2;if(strcmp(temp1,temp2)){cout<<"两次密码不相同,请重输!"<<endl;break;}cout<<"密码设置成功!"<<endl;strcpy(code,temp1);     //保存新密码break;}return 1;
}int Cdisk::createuser()        //准备创建新用户
{char n[10],c[10];int i=0,j;for(i=0;i<3;i++)if(user[i].get_status()==0)        //是否有此用户,此尚未存在break;if(i==3){cout<<"已经达到最大用户3个,不能再创建!"<<endl;return 0;}user[i].set_status(1);      //为新用户分配权利cout<<"请输入用户名:"<<endl;cin>>n;if(i>0)            //已有其它用户存在{for(j=0;j<i-1;j++)if(!strcmp(user[j].get_name(),n)){cout<<"此用户名已存在!"<<endl;return 0;}}cout<<"请输入密码:"<<endl;cin>>c;user[i].set_user(n,c);       //调用Cuse的成员函数,传递用户名与密码cout<<"用户创建成功!"<<endl;return 1;
}int Cdisk::first_dele_user()       //删除用户
{char n[10],c;int i;cout<<"请输入你要删除的用户名"<<endl;cin>>n;for(i=0;i<3;i++)     //在查找用户的同时,得到用户序号iif(!strcmp(user[i].get_name(),n)&&user[i].get_status())break;      //找到,跳出if(i==3){cout<<"出错,此用户不存在!"<<endl;return 0;}cout<<"确认删除此用户?确认Y,取消任意键"<<endl;cin>>c;if(c!='Y'&&c!='y'){cout<<"已经取消删除!"<<endl;return 0;}this->dele_user(i);cout<<"用户删除成功"<<endl;return 1;
}test::test()       //构造函数,初始化成员
{status=0;     //用户权利,即是否被创建标记length=0;        //空间now=0;         //当前目录Fhead=0;     //文件Dhead=0;       //目录
}test::~test()      //析构,清除程序占用的内存
{disk_empty+=length;length=0;PCB *f=Fhead;DIR *d=Dhead;while(f!=0)        //文件{if(f->next==0){this->dele_file(f);f=0;break;}while(f->next->next!=0)f=f->next;this->dele_file(f->next);f->next=0;f=Fhead;}while(d!=0)      //目录{if(d->next==0){this->dele_dir(d);d=0;break;}while(d->next->next!=0)d=d->next;this->dele_dir(d->next);d->next=0;d=Dhead;}
}int test::createfile()     //建立新文件
{int i=0,j=0;PCB *f,*p=0;DIR *D;p=new PCB;              //开辟一个新的文件结构体if(p==0){cout<<"无可用内存空间,创建文件失败!"<<endl;return 1;}cout<<"请输入建立的文件名:";cin>>p->name;if(now==0)            //根目录下的文件链f=Fhead;else             //当前目录下的文件链f=now->File_head;while(f!=0)            //检查是否文件重名{if(!strcmp(p->name,f->name)){cout<<"此文件已存在!"<<endl;return 0;  //退出}f=f->next;}cout<<"\n"<<"长度:";cin>>p->length;cout<<"\n"<<"属性(0:只读,1:读写):";cin>>p->attribute;cout<<endl;if(p->length>disk_empty)        //空间不足{cout<<"文件太大,空间不足,当前空间为:"<<disk_empty<<endl;delete p;return 0;}disk_empty=disk_empty-p->length;  //剩余空闲盘块//for(i=0;i<p->length&&i<10;i++)        //文件较小时,直接地址,文件数据盘块号for(j;j<10000;j++)               if(disk_block[j]==0)      //空闲{p->a[i]=j;             //得到此空间disk_block[j]=1;        //标记为已分配出去j++;break;                  //跳出寻找,为文件分配下一空间}p->p1=0;                    //一级索引p->p2=0;                  //二级索引if(p->length>10)            //超过10,用一级索引{p->p1=new int[100];     //为一级索引分配100个空间for(i=10;i<p->length&&i<110;i++)for(j;j<10000;j++)      //j,继续前面的值if(disk_block[j]==0){(p->p1)[i-10]=j;disk_block[j]=1;j++;break;}if(p->length>110)           //超过110,得用二级索引{p->p2=new int[100][100];  //在一级索引的基础上,2维for(i=110;i<p->length;i++)for(j;j<10000;j++)     //j,继续前面的值if(disk_block[j]==0){int m=(i-110)/100;     //行int k=(i-110)%100;      //列p->p2[m][k]=j;disk_block[j]=1;j++;break;}}}if(now==0)   //根目录下的文件{p->next=Fhead;    //后继结点指向头,即新指点在前Fhead=p;    //新结点在头}else{p->next=now->File_head;now->File_head=p;}length+=p->length;    //用户总空间大小增加if(now!=0)          //子目录下空间大小增加{now->length+=p->length;D=now->above;   //上一级目录while(D!=0)     //上级目录(根目录已实现)空间增加{D->length+=p->length;D=D->above;       //逐级向上}}return 0;
}int test::new_dir()        //建立新目录
{DIR *p,*h;cout<<"请输入新目录的名字:"<<endl;p=new DIR;cin>>p->name;      //目录名p->Dir_head=0;     //目录下的目录链为空p->length=0;     //p->File_head=0;       //目录下的文件为空if(now==0)          //当前为主目录h=Dhead;   //第一次时,h=0;指向目录链elseh=now->Dir_head;//当前的目录链while(h!=0) //此目录下存在其它子目录{if(!strcmp(h->name,p->name)){cout<<"此目录已存在!"<<endl;return 0;}h=h->next;}if(now==0)       //当前为主目录{p->above=0;        //主目录里目录的上一结点为0p->next=Dhead;       //把原目录接入新目录后面(Dhead初始为0)Dhead=p;     //Dhead始终指向最新目录结点}else{p->above=now;        //当前目录为新目录的上一结点p->next=now->Dir_head;    //反序插入新目录now->Dir_head=p;   //更新目录链}cout<<"目录创建成功"<<endl;return 1;
}int test::goback()     //向上返回
{if(now==0){cout<<"已是主目录,不能向上!"<<endl;return 0;}now=now->above;       //上一结点return 1;
}int test::open_dir()   //打开目录
{char name[10];DIR *p;if(now==0)  //当前主目录p=Dhead;elsep=now->Dir_head;    //p指向目录链cout<<"请输入你要打开的目录名:"<<endl;cin>>name;//int flag=0;while(p!=0){if(strcmp(p->name,name)==0){now=p;       //找到目录,now标记return 1;}p=p->next;}cout<<"当前没此目录"<<endl;return 0;
}int test::first_dele_file()                         //删除文件的前面工作
{char temp[10],a[5];cout<<"你要删除的文件名:"<<endl;cin>>temp;PCB *f=Fhead; //数据文件头指针PCB *above=0;if(now!=0)f=now->File_head; //当前目录下的数据文件while(f!=0){if(!strcmp(f->name,temp))break; //找到,跳出above=f; //标记第一个文件f=f->next;}if(f==0){cout<<"此文件不存在"<<endl;return 0;}cout<<"确定删除"<<f->name<<"文件吗?按0确定,其他键取消"<<endl;cin>>a;if(a[0]!='0'){cout<<"已取消删除文件。"<<endl;return 0;}disk_empty+=f->length; //回收此数据文件的空间大小if(now==0)  //根目录{if(f==Fhead)Fhead=Fhead->next;elseabove->next=f->next;}else{DIR *d=now;while(d!=0){d->length=f->length;d=d->above;}if(f==now->File_head)now->File_head=now->File_head->next;elseabove->next=f->next;}length-=f->length;this->dele_file(f);cout<<"删除成功"<<endl;return 1;
}int test::dele_file(PCB *f)                       //具体实现删除文件
{int i=0,m;for(i=0;i<10&&i<f->length;i++)  //回收文件具体空间,重置空闲{m=f->a[i];disk_block[m]=0;}if(f->p1!=0) //回收一级索引{for(i=10;i<110&&i<f->length;i++){m=f->p1[i-10];disk_block[m]=0;}delete[](f->p1);}if(f->p2!=0)  //回收二级索引{for(i=110;i<f->length;i++){m=(f->p2)[(i-110)/100][(i-110)%100];disk_block[m]=0;}delete[](f->p2);delete f;}f=0;   //要删除的文件为空了return 1;
}int test::first_dele_dir() //删除目录的前奏
{char n[10];char c;DIR *p,*above=0;p=Dhead;   //指向根目录下的目录链if(now!=0)p=now->Dir_head; //指向当前目录下的目录链cout<<"要删除的目录名:"<<endl;cin>>n;while(p!=0){if(!strcmp(p->name,n))break;  //找到要删除的目录,跳出above=p;   //保存前一结点p=p->next;}if(p==0){cout<<"没有这个目录!"<<endl;return 0;}cout<<"确定删除当前目录及此目标上的所有信息吗?按0确定,其他键取消"<<endl;cin>>c;if(c!='0')return 0;disk_empty+=p->length;  //回收磁盘空间if(now==0){if(p==Dhead) //如果是根目录下头结点,直接移动DheadDhead=Dhead->next;elseabove->next=p->next;//中间抽掉目标}else{if(p==now->Dir_head)now->Dir_head=now->Dir_head->next;elseabove->next=p->next;above=now; //当前目录while(above!=0){above->length-=p->length;//用above标记当前目录,进行大小更新above=above->above;  //向上一级}}length-=p->length;  //根目录大小更新this->dele_dir(p);p=0;cout<<"删除成功!"<<endl;return 1;
}int test::dele_dir(DIR *p) //具体实现删除目录的工作
{int flag=0;DIR *d=p->Dir_head;    //当前目录下的目录链表PCB *f=p->File_head;    //当前目录下的文件链if(f!=0){while(p->File_head->next!=0)//删除目录里的文件{f=p->File_head;while(f->next->next!=0)f=f->next;this->dele_file(f->next);f->next=0;}if(p->File_head->next==0){this->dele_file(p->File_head);   //删除头文件p->File_head=0;}}if(d!=0)  //删除目录下的目录{while(p->Dir_head->next!=0){d=p->Dir_head;while(d->next->next!=0)d=d->next;this->dele_dir(d->next);d->next=0;}if(p->Dir_head->next==0){this->dele_dir(p->Dir_head);//删除目录链头结点p->Dir_head=0;}}delete p; //释放p占用的内存p=0;     //置0return 1;
}int test::dis_now()    //显示当前目录
{DIR *d=Dhead;PCB *f=Fhead;if(now!=0){d=now->Dir_head;   //当前目录下的目录链f=now->File_head;}if(d==0&&f==0){cout<<"当前目录为空"<<endl;return 0;}cout<<"当前目录大小:";if(now==0)cout<<length;elsecout<<now->length;cout<<endl;if(d==0)cout<<"当前目录下没有目录"<<endl;else{cout<<"当前目录下包含如下目录:"<<endl;cout<<setw(14)<<"目录名称"<<setw(14)<<"目录大小"<<endl;while(d!=0){cout<<setw(14)<<d->name<<setw(14)<<d->length<<endl;d=d->next;}}if(f==0)cout<<"当前目录下没有文件"<<endl;else{cout<<"当前目录下包含如下文件:"<<endl;cout<<setw(14)<<"文件名称"<<setw(14)<<"文件大小"<<setw(14)<<"文件属性"<<endl;while(f!=0){cout<<setw(14)<<f->name<<setw(14)<<f->length<<setw(14)<<f->attribute<<endl;f=f->next;}}return 1;
}int test::open_file()  //打开文件
{char n[10];cout<<"请输入要打开的文件名"<<endl;cin>>n;PCB *f=Fhead;  //文件头指针if(now!=0)f=now->File_head; //指向文件while(f!=0){if(!strcmp(f->name,n)){cout<<"文件打开成功"<<endl;return 1;}f=f->next;}cout<<"当前目录无此文件"<<endl;return 0;
}DIR *test::get_now()   //得到当前目录路径
{return now;
}int test::set_user(char *n,char *c)//建立用户与密码
{strcpy(name,n);strcpy(code,c);status=1;return 1;
}void test::set_status(int b)//标记分配
{status=b;
}int test::get_status()//探取是否分配
{return status;
}const char* test::get_code()//得到密码
{return code;
}const char* test::get_name()//得到名字
{return name;
}int test::get_length()//得到长度
{return length;
}int test::dis_dir(DIR *d)//显示目录
{if(d==0)return 0;if(d->above!=0)this->dis_dir(d->above);//递归调用此功能cout<<"    "<<d->name<<'\n';return 0;
}int test::dis_file()//查看文件
{int i;char n[10];PCB *f=Fhead;if(now!=0)f=now->File_head;cout<<"请输入要查看的文件名:"<<endl;cin>>n;while(f!=0){if(!strcmp(n,f->name))  //找到此文件,跳出break;f=f->next;}if(f==0){cout<<"当前目录下没此文件"<<endl;return 0;}if(f->attribute==0)cout<<"此为只读文件,";elsecout<<"此为读写文件,";cout<<"占用硬盘块号如下:"<<endl;for(i=0;i<f->length&&i<10;i++)      //直接存放的{cout<<setw(6)<<f->a[i];if((i+1)%10==0)cout<<endl;}for(i=10;i<f->length&&i<110;i++)  //一级索引存放的{cout<<setw(6)<<f->p1[i-10];if((i+1)%10==0)cout<<endl;}for(i=110;i<f->length;i++) //二级索引存放的{cout<<setw(6)<<f->p2[(i-110)/100][(i-110)%100];if((i+1)%10==0)cout<<endl;}cout<<endl;return 1;
}int test::dele_user()//删除用户
{length=0; //用户空间置0Fhead=0;Dhead=0;now=0;status=0;return 1;
}int main()
{char c;Cdisk D;                   //管理员类的对象int i=1,n,flag=1,t=0;while(flag){cout<<"---------------多用户文件系统----------------"<<endl;cout<<"        1.管理员"<<endl;cout<<"        2.用户登录"<<endl;cout<<"        3.退出"<<endl;cout<<endl;cout<<""<<endl;cout<<"请选择操作:";cin>>c;switch(c){case '1':n=D.login(c);flag=1;system("cls");cout<<"管理员登录成功!"<<endl;while(flag){cout<<""<<endl;cout<<"1.创建用户"<<endl;cout<<"2.删除用户"<<endl;cout<<"3.查看当前用户"<<endl;cout<<"4.返回登录窗口"<<endl;cout<<"---------------------------"<<endl;cout<<"请选择操作:";cin>>c;cout<<endl;switch(c){case '1':D.createuser();break;case '2':D.first_dele_user();break;case '3':D.dis_disk();break;case '4':/*{if(t==0) //t作标记,防止重复设置密码出错strcpy(D.code,"123");D.set_code();t++;break;}*/ {flag=0;system("cls");}/*case '5':{flag=0;system("cls");}*/ break;default:cout<<"请输入1-4!"<<endl;}}flag=1;break;case '2':n=D.login(c);if(n==-1)break;while(flag){cout<<"----------------------------------------------"<<endl;cout<<"1.创建文件         2.删除文件"<<endl;cout<<"3.创建目录         4.删除目录"<<endl;cout<<"5.打开目录         6.返回上一级目录"<<endl;cout<<"7.查看当前目录     8.查看文件"<<endl;cout<<"0.退出"<<endl;cout<<"-----------------------------------------------"<<endl;cout<<"用户:"<<D.user[n].get_name()<<'\n'<<"目录为:\nroot\n";D.user[n].dis_dir(D.user[n].get_now());cout<<endl;cout<<"请输入选择:";cin>>c;cout<<endl;switch(c){case '1':D.user[n].createfile();break;case '2':D.user[n].first_dele_file();break;case '3':D.user[n].new_dir();break;case '4':D.user[n].first_dele_dir();break;case '5':D.user[n].open_dir();break;case '6':D.user[n].goback();break;case '7':D.user[n].dis_now();break;case '8':D.user[n].dis_file();//D.user[n].set_code();break;case '0':{flag=0;system("cls");}break;default:cout<<"请输入0-9"<<endl;}}flag=1;break;case '3':flag=0;break;default:cout<<"请输入1-3!"<<endl;}}
}

操作系统课程设计报告(文件系统)相关推荐

  1. linux课程设计题目主存空间的分配与回收,可变分区分配与回收,哈尔滨理工大学操作系统课程设计报告.doc-资源下载在线文库www.lddoc.cn...

    可变分区分配与回收,哈尔滨理工大学 操作系统课程设计报告.doc 哈 尔 滨 理 工 大 学 课 程 设 计 ( 操 作 系 统 ) 题 目 可变分区分配与回收 (首次适应算法) 班 级 计算机科学与 ...

  2. 华科计算机课程设计,华中科大操作系统课程设计报告(附源码).doc

    华中科技大学计算机学院 操作系统课程设计报告 班级: 学号: 姓名:彭博 时间:2010年3月 设计内容一:熟悉和理解Linux编程环境 编写一个C程序,实现文件拷贝功能. 2)编写一个C程序,使用下 ...

  3. 华中科技大学计算机课程设计,华中科技大学计算机学院操作系统课程设计报告[1] (精选可编辑)...

    <华中科技大学计算机学院操作系统课程设计报告[1] (精选可编辑)>由会员分享,可在线阅读,更多相关<华中科技大学计算机学院操作系统课程设计报告[1] (精选可编辑)(27页珍藏版) ...

  4. 操作系统课程设计报告2021-2022——pintos

    操作系统课程设计报告 2021-2022 目录 操作系统课程设计报告 2021-2022 第一章 实验项目介绍 环境配置 ( 一 ). Ubuntu 服务器搭建 图形界面搭建 ( 二 ). Pinto ...

  5. 操作系统课程设计报告总结(下)

    操作系统课程设计报告总结(下) 实验六 银行家算法的模拟与实现 实验目的 总体设计 背景知识 基本原理 模块介绍 详细设计 关键代码及分析 实验结果与分析 小结与心得体会 银行家算法源码 实验七 磁盘 ...

  6. 操作系统作业调度算法c语言,操作系统课程设计报告电梯调度算法c语言实现.doc...

    操作系统课程设计报告电梯调度算法c语言实现 操作系统课程设计报告电梯调度算法c语言实现 :调度 算法 电梯 课程设计 操作系统 操作系统课程设计报告 模拟操作系统课程设计 写一个简单的操作系统 篇一: ...

  7. java编写文件系统的方法_操作系统课程设计模拟文件系统Java

    [实例简介] 一个操作系统课程设计,使用java语言模拟磁盘文件系统实现,实现了FAT算法 [实例截图] [核心代码] e692cc3b-c785-40f6-babe-2f9d5383f034 └── ...

  8. 操作系统课程设计--简单文件系统的实现

    #include <stdio.h> #include <memory.h> #include <string> #include <iostream> ...

  9. 操作系统课程设计-二级文件系统,Windows平台版本,c语言

    支持命令: ls:简要展示当前目录内容 ll :详细内容(设计中目录大小不计) cd :切换目录 chmod:更改文件或者目录的权限,需要输入700,644这种类型 pwd:显示当前目录 userad ...

  10. 操作系统课程设计-二级文件系统,Linux平台版本,c语言

    头文件: #ifndef MYSYSTEM_H_INCLUDED #define MYSYSTEM_H_INCLUDED #include <stdio.h> #include <s ...

最新文章

  1. AI 创业周报第4期:AI芯片创企重磅发力,左手医生完成亿元 B 轮融资
  2. 服务器otter部署-实现MySql数据同步
  3. Electron 开发环境下总是 crash
  4. Pycharm Pro 2018.2 汉化专业激活破解
  5. android wifi驱动_OTT盒子WiFi方案首选:博通2T2R WiFi模块
  6. Node.js 切近实战(十一) 之实时通讯
  7. 2016年深圳市宝安区小一学位申请流程及时间安排
  8. Eclipse中执行Ant脚本出现Could not find the main class的问题及解
  9. [转载] python元组 tuple
  10. 基于主动学习和克里金插值的空气质量推测
  11. 飞秋官方下载 访问我博客也有近一半的用户
  12. 【Flink】Flink 使用代码如何主动触发 SavePoint
  13. 大数据之-Hadoop源码编译_编译hadoop源码前_需要准备的软件_以及编译步骤---大数据之hadoop工作笔记0045
  14. 每日长难句打卡Day22
  15. 如何在Kubernetes容器环境下部署Spinnaker?
  16. 实现字符级的LSTM文本生成
  17. 语言自制教具_学习笔记:蒙特梭利教师必备硬核技能“蒙氏理论+教具制作”...
  18. c语言串口调试助手源码,串口调试工具 1.02 (软件 + 源码)
  19. 关于微信小程序下拉刷新、上拉触底方法的实现
  20. 重新认识JavaScript面向对象: 从ES5到ES6

热门文章

  1. 个税抵扣全指南精华版!
  2. GBase数据库系统操作
  3. sh文件执行的时候卡住的可能原因
  4. 论分布式存储系统架构设计
  5. 数据分析师mysql面试题_30个sql面试题及答案(数据分析师福利)
  6. r语言 wiod_数据可视化基本套路总结
  7. 北京理工大学—计算机专业课程资源
  8. LTE通讯相关2:频带、信道带宽和频点号EARFCN
  9. 读书笔记3——《用户故事与敏捷方法》
  10. spring定时器时间表达式 Quartz中时间表达式的设置