1、實驗概述
- 實作多使用者檔案系統,每次使用者可儲存多個檔案,一次運作使用者可打開5個檔案。
- 實作檔案的相關操作,包括建立、删除、打開、關閉以及讀寫功能。
- 采用二級目錄,設定主目錄MFD、使用者檔案目錄UFD。
- 設定檔案權限保護碼:1-可執行,2-隻讀,3-隻寫。
- 實作使用者登入、退出、退出系統等操作。
- 為簡化程式,不對使用者資訊進行儲存,即每次運作,檔案系統都相當于初始化一次。
2、結構體設計
(1)使用者users
typedef struct users
{
char name[8]; //使用者名
char pwd[10]; //密碼
}users;
(2)主檔案目錄MFD
struct MFD{ // 主檔案目錄
string u_name; // 使用者名
int addr; // 指向子目錄指針
}mfd[10];
(3)使用者檔案目錄UFD
struct UFD{ // 使用者檔案目錄
File file[1000];
string u_name; // 使用者名
int id; // 檔案的總數
int cnt; // 使用者檔案存在的個數
int open_cnt; // 使用者打開檔案個數,最大為k
void init() ; //初始化資料項
void create() ; //建立使用者檔案
void del(int pos); //删除使用者檔案
void open(int pos); //打開檔案
void close(int pos); //關閉檔案
void read(int pos); //讀檔案
void write(int pos); //寫檔案
int Find(string name);//根據檔案名查找檔案
}ufd[10];
(4)檔案File
struct File{
string name; // 檔案名
bool exist; // 0表示檔案已經删除,1表示檔案存在
bool state; // 0表示檔案處于關閉狀态,1表示打開狀态
int protect; // 1表示隻執行,2表示隻讀,3表示隻寫,4表示可讀可寫
string content; // 檔案内容
void create(); //建立
void del(); //删除
bool open(); //打開
bool close(); //關閉
void read(); //讀
void write(); //寫
};
3、檔案系統的流程圖

4、代碼實作
(1)User.h
頭檔案裡新加使用者資訊,用于登入,這種實作方法簡單,使用者資訊固定。
當然,也可以嘗試建立一個檔案存儲使用者資訊,登陸時将輸入的賬号密碼與檔案已有資料比較,隻是考慮到這次實驗的重點在于體驗多使用者系統,故而一切從簡。
typedef struct users
{
char name[8];
char pwd[10];
}users;
users usrarray[8] =
{
"usr1","usr1",
"usr2","usr2",
"usr3","usr3",
"usr4","usr4",
"usr5","usr5",
"usr6","usr6",
"usr7","usr7",
"usr8","usr8",
};
(2)UFD.h等隻是上述的結構體,無追加内容
(3)File.h
struct File{
string name; // 檔案名
bool exist; // 0表示檔案已經删除,1表示檔案存在
bool state; // 0表示檔案處于關閉狀态,1表示打開狀态
int protect; // 1表示隻執行,2表示隻讀,3表示隻寫,4表示可讀可寫
string content; // 檔案内容
void create();
void del();
bool open();
bool close();
void read();
void write();
};
void File::create(){
cout << "請輸入檔案名與檔案權限(1隻執行 2隻讀 3可寫): "; cin >> name >> protect;
cout << "請輸入檔案内容: "; cin >> content;
exist = 1;
state = 0;
}
void File::del(){
exist = 0;
}
bool File::open(){
if(protect == 1) { cout << "打開失敗,該檔案為隻執行檔案!" << endl; return 0;}
else if(state == 1) { cout << "該檔案已處于打開狀态" << endl; return 0;}
else { state = 1; cout << "打開成功" << endl; return 1;}
}
bool File::close(){
if(state == 0) { cout << "該檔案已處于關閉狀态" << endl; return 0;}
else { state = 0; cout << "關閉成功" << endl; return 1;}
}
void File::read(){
if(protect == 1) { cout << "讀檔案失敗,該檔案為隻執行檔案!" << endl; }
else { cout << content << endl;}
}
void File::write(){
if(protect==1 || protect==2) { cout << "寫檔案失敗,該檔案不可寫" << endl;}
else {
string cont; cout << "請輸入寫入内容: "; cin >> cont;
content=cont; cout << "寫入成功!" << endl;
}
}
(4)main.cpp
#include <iostream>
#include<stdlib.h>
#include <cstdio>
#include <cstring>
#include <string>
#include "File.h"
#include "User.h"
using namespace std;
struct MFD{ // 主檔案目錄
string u_name; // 使用者名
int addr; // 指向子目錄指針
}mfd[10];
int mfdcnt = 8; // 使用者數
int k = 5; // 每個使用者最多打開的檔案數
struct UFD{ // 使用者檔案目錄
File file[1000];
string u_name; // 使用者名
int id; // 檔案的總數
int cnt; // 使用者檔案存在的個數
int open_cnt; // 使用者打開檔案個數,最大為k
void init() { cnt=0; open_cnt=0; id=0;}
void create() { file[id].create(); cnt++; id++;}
void del(int pos) { file[pos].del(); cnt--;}
void open(int pos) {
if(open_cnt == k) cout<<"您已經打開了"<<k<<"個檔案,不能再打開了" << endl;
else {
if(file[pos].open() == 1) open_cnt++;
}
}
void close(int pos) { if(file[pos].close() == 1) open_cnt--; }
void read(int pos) { file[pos].read(); }
void write(int pos) { file[pos].write(); }
int Find(string name) {
int pos = -1; // 需要操作檔案的位置
for(int i=0; i<id; i++)
if(file[i].exist==1 && file[i].name==name) return pos=i;
cout << "找不到該檔案,請檢查檔案名\n";
return pos;
}
}ufd[10];
void see(string u_name){
int addr = -1;
for(int i=0; i<mfdcnt; i++){
if(mfd[i].u_name == u_name) addr = mfd[i].addr;
}
if(addr == -1) { cout << "沒有該使用者" << endl;}
else{
UFD user = ufd[addr];
cout << "********************使用者名" << u_name << "********************\n";
cout << "檔案個數: " << user.cnt << "\t檔案打開數: " << user.open_cnt << endl;
cout << "檔案名\t檔案狀态\t檔案權限\t檔案内容\n";
for(int i=0; i<user.id; i++){
File f = user.file[i];
if(f.exist == 0) continue;
cout << f.name << "\t";
if(f.state == 0) cout << "關閉\t\t";
else cout << "打開\t\t";
if(f.protect == 1) cout << "隻執行\t\t";
else if(f.protect == 2) cout << "隻讀\t\t";
else if(f.protect == 3) cout << "可寫\t\t";
cout << f.content << endl;
}
}
}
void menu(){
printf("************* 操作目錄 *****************\n");
printf("************* 0: 退出 *****************\n");
printf("************* 1: 建立檔案 *****************\n");
printf("************* 2: 删除檔案 *****************\n");
printf("************* 3: 打開檔案 *****************\n");
printf("************* 4: 關閉檔案 *****************\n");
printf("************* 5: 讀檔案 *****************\n");
printf("************* 6: 寫檔案 *****************\n");
printf("************* 7: 檢視UFD *****************\n");
printf("************* 8: 退出目前使用者 *****************\n");
}
void operate(){
string u_name;
cout << "請輸入登入使用者名稱: "; cin >> u_name;
int u_id = -1;
for(int i=0; i<mfdcnt; i++){
if(mfd[i].u_name == u_name){
while(1){
cout<<"輸入密碼:"; string pwd; cin>>pwd;
if(pwd == usrarray[i].pwd)
{
cout<<"密碼正确,登入成功!"<<endl;
u_id = mfd[i].addr;
break;
}
else{
cout<<"密碼錯誤。"<<endl;
}
}
}
}
if(u_id == -1) { cout << "沒有該使用者" << endl; return ;}
system("pause");
while(1){
system("cls");
menu();
int op; cin >> op;
if(op == 0) break;
if(op == 1) ufd[u_id].create();
else if(op == 7) see(u_name);
else if(op == 8){
cout << "請輸入登入使用者名稱: "; cin >> u_name;
for(int i=0; i<mfdcnt; i++){
if(mfd[i].u_name == u_name){
while(1){
cout<<"輸入密碼:"; string pwd; cin>>pwd;
if(pwd == usrarray[i].pwd)
{
cout<<"密碼正确,登入成功!"<<endl;
u_id = mfd[i].addr;
break;
}
else{
cout<<"密碼錯誤。"<<endl;
}
}
}
}
}
else {
string name;
cout << "請輸入操作檔案名: "; cin >> name;
int pos = ufd[u_id].Find(name);
if(pos == -1) continue;
if(op == 2) ufd[u_id].del(pos);
else if(op == 3) ufd[u_id].open(pos);
else if(op == 4) ufd[u_id].close(pos);
else if(op == 5) ufd[u_id].read(pos);
else if(op == 6) ufd[u_id].write(pos);
}
system("pause");
}
}
void InitUser(){
for(int i=0; i<mfdcnt; i++){
mfd[i].u_name = usrarray[i].name; mfd[i].addr = i;
ufd[i].u_name = usrarray[i].name;
}
}
int main(){
cout << "目前使用者數m: "; cout<< mfdcnt<<endl;
cout << "使用者最多可以打開的檔案數: "; cout<<k<<endl;
InitUser();
while(1){
operate();
cout << "還要繼續操作嗎? (0 or 1): ";
int op; cin >> op; if(op == 0) break;
}
}
4、一些測試截圖
(1)登入usr1
(2)在usr1使用者目錄下建立檔案test1,權限為隻讀;test2,權限為可寫
(3)檢視usr1使用者主目錄下檔案
(4)切換使用者,重複建立檔案,檢視檔案過程
5、總結
本篇部落格内容隻是對多使用者檔案系統的一個簡單模拟。簡易檔案系統的功能基本都實作了。在檔案系統中,可以進行使用者切換、使用者登入、在使用者檔案目錄下進行檔案的相關操作、顯示使用者的UFD等。
但是,其實本檔案系統還是有提升空間,因為檔案系統沒有實作資訊存儲功能,運作結束後,不存儲使用者資訊以及使用者的檔案資訊,每次運作都相當于初始化一遍。
僅供參考,謝謝。