第一篇:AIX新建文件系统
AIX系统新建文件系统操作文档
1.概述 1.1.目的
AIX新建文件系统操作步骤文档,提供给对AIX新建文件系统的人员没有操作过或没有经验者参考。
1.2.来源
AIX新建文件系统yuli,用于备份数据库数据使用。
1.3.重要程度
重要
1.4.描述
在AIX操作系统中新建文件系统操作步骤。
2.处理步骤 2.1.一般新建步骤
1.连接到需要新建文件系统的服务器检查环境是否符合新建文件系统的要求。2.检查卷组及卷组的大小,其中命令:lspv(查看有什么卷组),lspv 卷组名称(查看某个卷组的使用情况,如已用空间,空余空间等相关信息。)3.以东莞数据库服务器新建一个备份文件系统为例,在array2vg卷组新建文件系统,文件系统名称为:yuli,文件系统的大小为500G,具体操作如下:
/ 6
1)用root用户连接数据库服务器,查看array2vg使用情况(lsvg array2vg),使用情况如下图所示:从图中可以看到array2vg可用空间满足新建文件系统要求。2)Smitty hacmp(回车),如下图所示:选择:system Management(C-SPOC),回车,如下图所示:选择:HACMP Logical Volume Management,回车,如下图所示:选择:Shared File Systems,回车,如下图所示:选择:Enhanced Journaled File Systems,回车,如下图所示:
/ 6 选择:Add an Enhanced Journaled File System(新建增强型文件系统),回车,(注:若是在原有的逻辑卷上新建文件系统,则选择:Add an Enhanced Journaled File System on a Prcviously Defincd Logical Volume),如下图所示:选择相应卷组新建文件系统(array2vg),如下图所示:
/ 6 在图中填写文件系统的大小及文件系统加载路径后,回车,如下图所示:
3)看到Command:OK,则操作成功。按Esc+0 ,退出当前界面。4)用命令df –k,查看新建文件系统是否成功,如下图所示:
5)至此,新建文件系统结束。
2.2.遇到的问题
新建文件系统时发现初次新建不成功,系统的错误提示是: Command:fail MAXIMUM NUMBER OF LOGICAL PARTITIONS IS 512 在新建文件系统的逻辑卷中,MAXIMUM NUMBER OF LOGICAL PARTITIONS 这个值是512,不能满足新建文件系统大小的需求,所以创建文件系统不成功。解决此问题的操作步骤如下:
1)Smitty hacmp 回车,如下图:选择:system Management(C-SPOC),回车,如下图所示:
/ 6 选择:HACMP Logical Volume Management,回车,如下图所示:选择:Shared Logica Volumes,回车,如下图所示:选择:Change a Shared Logical Volume,回车,如下图所示:选择新建文件系统所在的逻辑卷(默认为lv01),回车,所下图所示:
/ 6 把MAXIMUM NUMBER OF LOGICAL PARTITIONS 这个值改为10240或者更大,然后回车,提示成功即可。注:
1.逻辑卷的属性修改完成后,按新建文件系统的步骤重新操作一次,即可新建成功。
2.所有的这些操作都必须是在HA上进行,如果不是在HA上进行操作,需在HA上把操作的内容进行同步。
/ 6
第二篇:模拟文件系统实验报告
操作系统大型试验
实验
报
告姓名:XX 班级:软件工程110x 学号:201126630xxx
一、名称
操作系统大型试验。
二、目的
用C++编写出一个简单的模拟文件系统,实现目录的添加、删除、重命名,文件的添加、删除、重命名、文件和目录、文件的拷贝。
三、要求
开发工具:word,vc win32api 1.设计和实现一个简单的文件系统,要求包括目录、普通文件和文件的存储 2.文件系统的目录结构采用类似Linux的树状结构; 3.要求模拟的操作包括:
a)目录的添加、删除、重命名; b)目录的显示(列表)
c)文件的添加、删除、重命名 d)文件和目录的拷贝
4.用户进入时显示可用命令列表;用户输入help时显示所有命令的帮助文档; 输入某个命令+?时显示该条命令的使用说明
5.用户输入exit时退出该系统 6.实验实现基于windows平台; 7.实验开发语言可以选用C/c++等
四、设计
1.主要思路说明
本模拟系统通过一个大小固定的数组要代表物理盘块,假设共有1024块,新增目录占一块,新增文件占一块,文件中可输入内容,内容假设定义为5个字符占一块,超出则应新申请空间。模拟物理盘块的数组中,数组内容为-99代表改物理盘块内容为空,可使用,其他数字均代表该物理盘块被占用,其中-3代表是占用文件的末结点,其他整数代表是文件内容的下一个寻址下标,另有一个string类型的数组来存储内容,模拟文件写入了对应下标的物理盘块中。设置了一个全局指针指向根结点,一个全局指针指向当前操作目录。搜索空白物理盘块时采用顺序搜索物理盘块数组。存储形式主要采用类似二叉树结构,如目录为根,目录下的第一个文件或目录存在根的子节点,目录下的其他文件或目录存在第一个文件或目录的兄弟节点,以此类推。
本程序仅seperate()函数使用现成代码,此函数功能为将输入命令串分离,仅仅起到美观作用,其余所有代码均为原创!
2.申优功能:
1)能实现动态增长,即当输入文件的内容大小大于分配的模拟物理盘块时系统能够自动寻找空物理盘块并分配,将超出的内容保存在新的物理盘块中,若超出模拟磁盘大小,则超出部分不保存且返回提示。
2)能实现级联删除,即当删除目录(文件夹)时,目录下的所有内容也应当删除并正确释放物理盘块空间。
3)能实现目录的复制,即复制目录时(文件夹)时,该目录下的所有文件和目录也应准确复制至目标目录中,并正确分配物理盘块空间。3.主要函数和类的定义
1)主要函数定义
#define show_bnum 20
//显示物理盘块的块数
#define block_size 1024
//物理盘块块数 int block[block_size];
//假设有block_size块物理盘块 string content[block_size];//存放文件内容 int Msize=5;
//此处为模拟磁盘大小为输入5个字符 fnode *root=new fnode(“WP:”,0,0);
//设置根目录 fnode *current_path=new fnode();
fnode *seek_flag=new fnode();
fnode *cp_flag=new fnode();
void initialize();
int seekTarget(string name);
int seek_log(string name);
void delete_node(string name);
int freeblock(fnode *);
int seekfreeblock();
void show_current_path();
void add_file(string name,int t);
void show_curpath_all();
void rename_file(string Oname,string Nname);void seperate();
void cd();
void add_File();
void add_Log();
void delete_file();
void show_memory();
void re_name();
void help();
void show_content();
void write_file();
void Clear_();
void Exit();
void cp();
void cp_log(fnode *target,fnode *source);void cp_file(fnode *target,fnode *source);void cp_node(fnode *target,fnode *source);int find_target_log();
int calculate_logsizeMain(fnode *);
int calculate_logsize(fnode *);2)文件节点类的定义: class fnode {
public:
//当前路径 //作为查找标志 //作为复制的位置标志 //初始化 //搜索文件或目录 //搜索目录 //删除节点 //释放物理盘块 //搜索可用物理盘块 //显示当前路径 //增加目录、文件 //显示当前目录下的所有文件//重命名 //分离命令 //进入目录 //增加文件功能入口 //增加目录功能入口 //删除文件或目录功能入口 //显示物理盘块占用情况 //重命名功能入口 //查看帮助 //查看文件内容 //写文件 //清屏 //退出 //复制功能入口 //复制目录 //复制文件 //复制节点 //找到复制的目标目录 //计算目录大小
string filename;
//文件名
int type;
//文件类型,1为普通文件,0为目录文件
fnode *parent;
//父节点
fnode *child;
//子节点
fnode *brother;
//兄弟节点
int block_num;
//表示占用的物理盘块块号
int isBro;
//表示是否是在同级目录下,0表示不是,1表示是
int isCld;
//是否为目录下第一个节点,1表示是,0表示不是
fnode()
//初始化
{
type=-1;
parent=NULL;
child=NULL;
brother=NULL;
block_num=-1;
isBro=0;
isCld=0;
}
fnode(string n,int t,int b)
//根节点初始化
{
type=t;
filename=n;
parent=NULL;
child=NULL;
brother=NULL;
block_num=b;
block[block_num]=-3;
isBro=0;
isCld=0;
}
fnode(fnode *p,string name,int t,int b)//文件节点初始化
{
parent=p;
filename=name;
type=t;
child=NULL;
brother=NULL;
block_num=b;
block[block_num]=-3;
isBro=0;
isCld=0;
}
void copy(fnode *cp)
//拷贝函数
{
filename=cp->filename;
type=cp->type;
parent=cp->parent;
child=cp->child;
brother=cp->brother;
block_num=cp->block_num;
}
};4.命令:
命令 echo md del cd cp dir ren typ wrt mem cls exit
解释
echo命令可以在当前目录下创建一个文件,具体格式:echo+name md命令可以在当前目录下创建一个目录文件,具体格式:md+name del命令可以在当前目录下删除一个已存在的文件或目录(支持级联删除),具体格式:del+name
cd命令可以进入下一级目录或返回上级目录、根目录,具体格式:cd+name或cd+.或cd+..cp命令可以复制当前目录下一个指定的文件或目录至指定的目录,具体格式:cp+name+road
dir命令可以显示当前目录下的所有文件和目录,具体格式:del ren命令可以重命名一个存在于当前目录下的文件或目录,具体格式:ren+name +new name typ命令可以查看当前目录下一个文件的内容,具体格式:typ+name wrt命令可以在当前目录下写内容至一个已存在的文件,具体格式:wrt+name +content mem命令可以查看模拟物理盘块的使用情况,具体格式:mem cls命令为清屏命令,具体格式:cls exit命令为退出命令,具体格式:exit
五、关键技术流程图及说明
提示:若图中文字无法看清,可用Micorsoft Visio打开压缩包下“部分程序流程图”文件夹的绘图文件查看。
1.增加文件或目录(此功能比较简单,流程图写的较详细就不做说明):
2.删除目录(实现级联删除):
说明:删除目录时删除文件和删除目录本身放在同一个函数中,删除目录下的所有文件放在freeblock函数里,这样比较好处理。下面给只给出递归函数的流程图。
3.将内容写入文件(实现动态增长):
说明:图中Msize为模拟规定的文件块字符串大小,比如Msize=5,那么一个物理盘块只能存5个字符,超出则要申请新的空间。主要采用双重循环方法写入,外层循环为需要的块数,内层循环为Msize,用string累加字符串内容,内层循环退出后新申请一个空间并将对应下标赋给上一个物理盘块数组,再将对应内容存入content(为string类型的数组,模拟存储内容)数组中,直至退出外层循环。
4.复制目录:
说明:这里和删除目录一样,写了两个复制函数,这样写同样因为递归调用是比较方便,第一个函数传入参数为目标目录指针和被复制的目录的指针,第一个函数里新建了一个阶段复制被复制的目录的内容,然后将新建节点的子节点和被复制目录的子结点传入下一个递归调用函数(因为目录的内容存于目录的子节点,与兄弟节点无关),第二个函数就是递归调用函数cp_node,下面就只给出cp_node的流程图(复制之前同样进行了路径的判误操作,内存大小的判断操作,是否重名的判断操作,被复制目录是否存在判断操作,这些操作在递归函数之前完成,所以下面的递归函数不体现这些操作)。
六、运行结果
1.主界面展示:
图:主界面展示
2.help命令展示:
图:help命令展示
3.echo命令展示:
图:echo命令展示
4.del命令展示:
图:del命令展示-普通删除
说明:创建了目录log1,在log1中创建一系列文件和目录,磁盘使用情况显示已分配,实用del删除命令后查看磁盘分配证明级联删除是可靠的。
图:del命令展示-级联删除 5.md命令展示:
图:md命令展示
6.cd命令展示:
说明:图中展示了cd+name、cd+.、cd+..三种cd命令的使用和判别情况。
图:cd命令展示
7.dir命令展示:
图:dir命令展示
8.typ命令展示:
图:typ命令展示
9.ren命令展示:
图:ren命令展示
10.wrt命令展示:
图:wrt命令展示 说明:此处为了实验方便,将磁盘大小限定为5,每块磁盘输入的字符数限2,输入的内容***899需要9块磁盘块,而磁盘块为5,根目录占用一块,只能输入4块大小的内容,即11223344,所有文件file只写入了11223344。
图:wrt动态增长展示
11.mem命令展示:
图:mem命令展示
12.cls命令展示:
图:cls命令展示-1
图:cls命令展示-2
13.cp命令展示:
说明:图中根目录(WP:)下创建了目录a(md a)、目录b(md b),在a目录下创建了b目录(md b),在b目录中创建了文件a(echo a)、目录c(md c),文件a中输入1111122222(wrt a 111112222)内容代表占了两块物理盘块(程序中Msize模拟大小,设为5个字符了),再进入目录c(cd c),c中先创建目录f(md f)再创建文件g(与之前创建顺序不同说明程序在不同情况下能正常运行),在g中输入5个3,5个2,5个1(wrt g ***)代表占用3块物理盘块空间,再返回目录a(cd.cd.),将目录a下的目录b复制给目录WP下的目录c(cp b WP:c),再将目录a中的目录b删除(del b证明的确是复制而非简单指针指向),进入WP下的目录c查看刚复制的内容(dir)。物理盘块使用情况中第一个-3为根目录占用,第二个-3是目录a,第三个-3是目录c,接下来的8个-99是目录a中原目录b占用的空间(此处证明删除是可靠的),图中显示目录c中确实成功复制了目录b及目录下的所有内容(使用dir命令查看)。
图:cp命令展示 14.exit命令展示:
图:exit命令展示
15.综合展示:
说明:echo a在根目录(WP:)下创建了文件a,md b在根目录(WP:)下创建了目录b,dir显示根目录下的所有文件和目录,wrt a aaaaabbbbbccccc在文件a中输入了一串内容,typ a显示文件a中的内容,cd b进入目录b,md a在目录b下创建了目录a,cd a进入目录a,cd.返回目录b,cd.返回根目录WP:,ren b newname将目录b重命名为newname,mem显示内存情况,第一个-3代表根节点占用,第二个3代表文件a占用且下一块盘块下标为3,第三个-3代表目录b占用,之后的4代表被文件a占用且的下一块盘块的寻找下标为4,下一个-3代表文件a的末盘块,下一个-3代表目录b内的目录a占用,del a在根目录WP:下删除文件a,mem查看物理盘块实验情况,图中显示原文件a占用的内存空间已经变为-99,代表成功删除a并释放磁盘空间(-99代表磁盘空间空闲可用),dir显示根目录WP:下所有文件和目录,显示只有newname,则证明重命名和删除操作是成功的。
图:综合展示
七、心得体会和调试中遇到的问题及解决办法
编写调试过程中遇到许多问题,一类是指针指向空还继续操作造成程序停止运行,经检查后修改正确,一类是逻辑上出现错误导致级联删除或者目录复制出错,经改正后成功实现。
主要的难点在于兄弟结点和子结点的处理,所以再程序中引入了isBro这个标志位来判断是否是兄弟结点即与父节点是否在同级目录,若不在同级目录则父节点为真父节点(是指向本目录而非本目录中上个文件)。还有一个难点是在进行递归调用删除或复制目录时发现处理目录和目录下的内容不太合适放在同一个递归程序中,所以单独写了两个函数处理目录的复制或删除,然后对应两个递归程序处理目录下的所有内容。实验总结及有待改进的问题。
因为时间比较紧张,在几门考试中抽空写了这个小程序,所以并没有实现存盘,另因为对输入命令字符串的处理上有点瑕疵,所有在写文件内容中只能写入连续的字符串(中间不能插入空格),否则会被判定为命令输入错误,并且只实现了文件的写入,不能修改或插入,有待改进。没有实现目录树的展示,只能显示目录下所有文件,有待改进。但相信时间再充裕一些这些小问题都能很好地解决。
八、源代码
在压缩包内“源代码”文件夹内。
第三篇:操作系统课程设计-文件系统
模拟一个简单二级文件管理系统
设计目的:通过具体的文件存储空间的管理、文件的物理结构、目录结构和文件操作的实现,加深对文件系统内部功能和实现过程的理解。
设计内容:模拟一个简单二级文件管理系统一、实验内容描述 1 实验目标
本实验的目的是通过一个简单多用户文件系统的设计,加深理解文件系统的内部功能及内部实现.2 实验要求
为DOS系统设计一个简单的二级文件系统.要求做到以下几点: ①可以实现下列命令: login 用户登录 dir 列文件目录 create 创建文件 delete 删除文件 open 打开文件 close 关闭文件 read 读文件 write 写文件
②列目录时要列出文件名、物理地址、保护码和文件长度.③源文件可以进行读写保护.二、程序主要内容
1设计思路
程序中要求每个用户在登陆后才可对其拥有的文件进行操作,用户对于其他用户的文件无操作权.文件操作包括浏览、创建、删除、打开、关闭、阅读、写入、修改模式.其他操作包括新建用户、帮助、用户登入、用户登出、退出系统.在程序文件夹下有个名为“file”的系统根目录,此目录下包括:一个名为“mfd”的文件,记录所有注册过的帐号及密码;用户文件,以用户名作为文件名,内容为其拥有的文件名及属性;一个名为“keiji”的文件夹.“keiji”文件夹中包括:“file.p”指针文件,记录所有已用的物理地址;一些以物理地址为名的文件,内容为文件内容.2 数据结构
file结构体系统文件数据结构:
fpaddrint,文件的物理地址、flengthint,文件长度、fmodeint,文件模式 0.只读;1.可写;2.可读写;3.保护、fname[]char,文件名; filemode结构体文件状态数据结构:
isopenint,文件当前状态,0.关闭;1.打开、modeint,文件模式 0.只读;1.可写;2.可读写;3.初始化;
user结构体用户信息数据结构:
uname[]char,用户名、upassword[]char,用户密码; userfile结构体用户文件数据结构:
uname[]char,用户名、ufile[]file,用户拥有的文件数组.代码:
#include
#include
#include
#include
#include
#define MaxUser 100
//定义最大MDF主目录文件
#define MaxDisk 512*1024
//模拟最大磁盘空间
#define commandAmount 12
//对文件操作的指令数
//存储空间管理有关结构体和变量
char disk[MaxDisk];
//模拟512K的磁盘存储空间
typedef struct distTable //磁盘块结构体
{
int maxlength;
int start;
int useFlag;
distTable *next;
}diskNode;
diskNode *diskHead;
struct fileTable
//文件块结构体
{
char fileName[10];
int strat;
//文件在磁盘存储空间的起始地址
int length;
//文件内容长度
int maxlength;
//文件的最大长度
char fileKind[3];
//文件的属性——读写方式
struct tm *timeinfo;
bool openFlag;
//判断是否有进程打开了该文件
//fileTable *next;
};
//两级目录结构体
typedef struct user_file_directory //用户文件目录文件UFD
{
//char fileName[10];
fileTable *file;
user_file_directory *next;
}UFD;
//UFD *headFile;
typedef struct master_file_directory //主文件目录MFD
{
char userName[10];
char password[10];
UFD *user;
}MFD;
MFD userTable[MaxUser];
int used=0;
//定义MFD目录中用已有的用户数
//文件管理
void fileCreate(char fileName[],int length,char fileKind[]);
//创建文件
void fileWrite(char fileName[]);
//写文件
void fileCat(char fileName[]);
//读文件
void fileRen(char fileName[],char rename[]);
//重命名文件
void fileFine(char fileName[]);
//查询文件
void fileDir(char UserName[]);
//显示某一用户的所有文件
void fileClose(char fileName[]);
//关闭已打开的文件
void fileDel(char fileName[]);
//删除文件
void chmod(char fileName[],char kind[]);
//修改文件的读写方式
int requestDist(int &startPostion,int maxLength);//磁盘分配查询
void initDisk();
//初始化磁盘
void freeDisk(int startPostion);
//磁盘空间释放
void diskShow();
//显示磁盘使用情况
//用户管理
void userCreate();
int login();
int userID=-1;
//用户登录的ID号,值为-1时表示没有用户登录
int main()
{
char order[commandAmount][10];
strcpy(order[0],“create”);
strcpy(order[1],“rm”);
strcpy(order[2],“cat”);
strcpy(order[3],“write”);
strcpy(order[4],“fine”);
strcpy(order[5],“chmod”);
strcpy(order[6],“ren”);
strcpy(order[7],“dir”);
strcpy(order[8],“close”);
strcpy(order[9],“return”);
strcpy(order[10],“exit”);
strcpy(order[11],“df”);
char command[50],command_str1[10],command_str2[10],command_str3[5],command_str4[3];
int i,k,j;
int length;
initDisk();
//初始化磁盘
for(i=0;i //初始化用户UFD目录文件的头指针 { userTable[i].user=(UFD *)malloc(sizeof(UFD)); userTable[i].user->next=NULL; } while(1) { printf(“********************************************n”); printf(“ 1、Creat usern”); printf(“ 2、loginn”); printf(“********************************************n”); printf(“Please chooce the function key:>”); int choice; scanf(“%d”,&choice); if(choice==1)userCreate(); else if(choice==2)userID=login(); else printf(“您的输入有误,请重新选择n”); while(userID!=-1) { fflush(stdin); printf(“———————————————————————————————————————n”); printf(“ create-创建 格式:create a1 1000 rw,将创建名为a1,长度为1000字节可读可写的文件n”); printf(“ rm-删除 格式:rm a1,将删除名为a1的文件n”); printf(“ cat-查看文件内容 格式:cat a1,显示a1的内容n”); printf(“ write-写入 格式:write a1n”); printf(“ fine-查询 格式:fine a1 ,将显示文件 a1的属性n”); printf(“ chmod-修改 格式:chmod a1 r,将文件a1的权限改为只读方式n”); printf(“ ren-重命名 格式:ren a1 b1 ,将a1改名为b1n”); printf(“ dir-显示文件 格式:dir aaa,将显示aaa用户的所有文件n”); printf(“ df-显示磁盘空间使用情况 格式:dfn”); printf(“ close-关闭文件 格式:close a1,将关闭文件a1n”); printf(“ return-退出用户,返回登录界面n”); printf(“ exit-退出程序n”); printf(“————————————————————————————————————————n”); printf(“please imput your command:>”); gets(command); int select; for(i=0;command[i]!=' '&&command[i]!=' ';i++) //command_str1字符串存储命令的操作类型 command_str1[i]=command[i]; k=i; command_str1[k]=' '; for(i=0;i { if(!strcmp(command_str1,order[i])) { select=i; break; } } if(i==commandAmount) { printf(“您输入的命令有误,请重新输入n”); continue; } for(i=k+1,k=0;command[i]!=' //commmand_str2字符串存储文件名或用户名 command_str2[k]=command[i]; command_str2[k]=' '; k=i; switch(select) { case 0:for(i=k+1,k=0;command[i]!=' ';i++,k++) command_str3[k]=command[i]; command_str3[k]=' '; k=i; j=1; length=0; //初始化文件长度 for(i=strlen(command_str3)-1;i>=0;i--) //把字符串转换为十进制 { length+=(command_str3[i]-48)*j; j*=10; } '&&command[i]!=' ';i++,k++) for(i=k+1,k=0;command[i]!=' '&&command[i]!=' ';i++,k++) command_str4[k]=command[i]; command_str4[k]=' '; fileCreate(command_str2,length,command_str4);break; case 1:fileDel(command_str2);break; case 2:fileCat(command_str2);break; case 3: fileWrite(command_str2);break; case 4:fileFine(command_str2);break; case 5:for(i=k+1,k=0;command[i]!=' '&&command[i]!=' ';i++,k++) command_str3[k]=command[i]; command_str3[k]=' '; chmod(command_str2,command_str3);break; case 6:for(i=k+1,k=0;command[i]!=' ';i++,k++) command_str3[k]=command[i]; command_str3[k]=' '; fileRen(command_str2,command_str3);break; case 7:fileDir(command_str2);break; case 8:fileClose(command_str2);break; case 9:UFD *p; for(p=userTable[userID].user->next;p!=NULL;p=p->next)//退出用户之前关闭所有打的文件 if(p->file->openFlag) p->file->openFlag=false; system(“cls”); userID=-1;break; case 10:exit(0);break; case 11:diskShow();break; } } } return 0; } void userCreate() { char c; char userName[10]; int i; if(used { printf(“请输入用户名:”); for(i=0;c=getch();i++) { if(c==13)break; else userName[i]=c; printf(“%c”,c); } userName[i]=' '; for(i=0;i { if(!strcmp(userTable[i].userName,userName)) { printf(“n”); printf(“该用户名已存在,创建用户失败n”); system(“pause”); return; } } strcpy(userTable[used].userName,userName); printf(“n”); printf(“请输入密码:”); for(i=0;c=getch();i++) { if(c==13)break; else userTable[used].password[i]=c; printf(“*”); } userTable[userID].password[i]=' '; printf(“n”); printf(“创建用户成功n”); used++; system(“pause”); } else { printf(“创建用户失败,用户已达到上限n”); system(“pause”); } fflush(stdin); } int login() { char name[10],psw[10]; char c; int i,times; printf(“请输入用户名:”); for(i=0;c=getch();i++) { if(c==13)break; else name[i]=c; printf(“%c”,c); } name[i]=' '; for(i=0;i { if(!strcmp(userTable[i].userName,name)) break; } if(i==used) { printf(“n您输入的用户名不存在n”); system(“pause”); return-1; } for(times=0;times<3;times++) { memset(psw,' ',sizeof(psw)); printf(“n请输入密码:”); for(i=0;c=getch();i++) { if(c==13)break; else psw[i]=c; printf(“*”); } printf(“n”); for(i=0;i { if(!strcmp(psw,userTable[i].password)) { printf(“用户登录成功n”); system(“pause”); break; } } if(i==used) { printf(“您输入的密码错误,您还有%d次输入机会n”,2-times); if(times==2)exit(0); } else break; } fflush(stdin); return i; } void initDisk() { diskHead=(diskNode *)malloc(sizeof(diskNode)); diskHead->maxlength=MaxDisk; diskHead->useFlag=0; diskHead->start=0; diskHead->next=NULL; } int requestDist(int &startPostion,int maxLength) { int flag=0;//标记是否分配成功 diskNode *p,*q,*temp; p=diskHead; while(p) { if(p->useFlag==0&&p->maxlength>maxLength) { startPostion=p->start; q=(diskNode *)malloc(sizeof(diskNode)); q->start=p->start; q->maxlength=maxLength; q->useFlag=1; q->next=NULL; diskHead->start=p->start+maxLength; diskHead->maxlength=p->maxlength-maxLength; flag=1; temp=p; if(diskHead->next==NULL)diskHead->next=q; else { while(temp->next)temp=temp->next; temp->next=q; } break; } p=p->next; } return flag; } void fileCreate(char fileName[],int length,char fileKind[]) { //int i,j; time_t rawtime; int startPos; UFD *fileNode,*p; for(p=userTable[userID].user->next;p!=NULL;p=p->next) { if(!strcmp(p->file->fileName,fileName)) { printf(“文件重名,创建文件失败n”); system(“pause”); return; } } if(requestDist(startPos,length)) { fileNode=(UFD *)malloc(sizeof(UFD)); fileNode->file=(fileTable *)malloc(sizeof(fileTable));//这一步必不可少,fileNode里面的指针也需要申请地址,否则fileNode->file指向会出错 strcpy(fileNode->file->fileName,fileName); strcpy(fileNode->file->fileKind,fileKind); fileNode->file->maxlength=length; fileNode->file->strat=startPos; fileNode->file->openFlag=false; time(&rawtime); fileNode->file->timeinfo=localtime(&rawtime); fileNode->next=NULL; if(userTable[userID].user->next==NULL) userTable[userID].user->next=fileNode; else { p=userTable[userID].user->next; while(p->next)p=p->next; p->next=fileNode; } printf(“创建文件成功n”); system(“pause”); } 为因 else { printf(“磁盘空间已满或所创建文件超出磁盘空闲容量,磁盘空间分配失败n”); system(“pause”); } } void freeDisk(int startPostion) { diskNode *p; for(p=diskHead;p!=NULL;p=p->next) { if(p->start==startPostion) break; } p->useFlag=false; } void fileDel(char fileName[]) { UFD *p,*q,*temp; q=userTable[userID].user; p=q->next; while(p) { if(!strcmp(p->file->fileName,fileName))break; else { p=p->next; q=q->next; } } if(p) { if(p->file->openFlag!=true) //先判断是否有进程打开该文件 { temp=p; q->next=p->next; freeDisk(temp->file->strat);//磁盘空间回收 free(temp); printf(“文件删除成功n”); system(“pause”); } else { printf(“该文件已被进程打开,删除失败n”); system(“pause”); } } else { printf(“没有找到该文件,请检查输入的文件名是否正确n”); system(“pause”); } } void fileCat(char fileName[]) { int startPos,length; int k=0; UFD *p,*q; q=userTable[userID].user; for(p=q->next;p!=NULL;p=p->next) { if(!strcmp(p->file->fileName,fileName)) break; } if(p) { startPos=p->file->strat; length=p->file->length; p->file->openFlag=true; //文件打开标记 printf(“*****************************************************n”); for(int i=startPos;k { if(i%50==0)printf(“n”);//一行大于50个字符换行 printf(“%c”,disk[i]); } printf(“nn*****************************************************n”); printf(“%s已被read进程打开,请用close命令将其关闭n”,p->file->fileName); system(“pause”); } else { printf(“没有找到该文件,请检查输入的文件名是否正确n”); system(“pause”); } } void fileWrite(char fileName[]) { UFD *p,*q; q=userTable[userID].user; int i,k,startPos; for(p=q->next;p!=NULL;p=p->next) { if(!strcmp(p->file->fileName,fileName)) break; } if(p) { if(!strcmp(p->file->fileKind,“r”)) //判断文件类型 { printf(“该文件是只读文件,写入失败n”); system(“pause”); return; } char str[500]; printf(“please input content:n”); gets(str); startPos=p->file->strat; p->file->openFlag=true; //文件打开标记 p->file->length=strlen(str); if(p->file->length>p->file->maxlength) { printf(“写入字符串长度大于该文件的总长度,写入失败n”); system(“pause”); return; } for(i=startPos,k=0;k<(int)strlen(str);i++,k++) disk[i]=str[k]; printf(“文件写入成功,请用close命令将该文件关闭n”); system(“pause”); } else { printf(“没有找到该文件,请检查输入的文件名是否正确n”); system(“pause”); } } void fileFine(char fileName[]) { UFD *p,*q; q=userTable[userID].user; for(p=q->next;p!=NULL;p=p->next) { if(!strcmp(p->file->fileName,fileName)) break; } if(p) { printf(“********************************************n”); printf(“文件名:%sn”,p->file->fileName); printf(“文件长度:%dn”,p->file->maxlength); printf(“文件在存储空间的起始地址:%dn”,p->file->strat); printf(“文件类型:%sn”,p->file->fileKind); printf(“创建时间:%sn”,asctime(p->file->timeinfo)); printf(“********************************************n”); system(“pause”); } else { printf(“没有找到该文件,请检查输入的文件名是否正确n”); system(“pause”); } } void chmod(char fileName[],char kind[]) { UFD *p,*q; q=userTable[userID].user; for(p=q->next;p!=NULL;p=p->next) { if(!strcmp(p->file->fileName,fileName)) break; } if(p) { strcpy(p->file->fileKind,kind); printf(“修改文件类型成功n”); system(“pause”); } else { printf(“没有找到该文件,请检查输入的文件名是否正确n”); system(“pause”); } } void fileRen(char fileName[],char name[]) { UFD *p,*q; q=userTable[userID].user; for(p=q->next;p!=NULL;p=p->next) { if(!strcmp(p->file->fileName,fileName)) break; } if(p) { while(q->next) { if(!strcmp(q->next->file->fileName,name)) { printf(“您输入的文件名已存在,重命名失败n”); system(“pause”); return; } q=q->next; } strcpy(p->file->fileName,name); printf(“重命名成功n”); system(“pause”); } else { printf(“没有找到该文件,请检查输入的文件名是否正确n”); system(“pause”); } } void fileDir(char userName[]) { UFD *p; int i,k; for(i=0;i { if(!strcmp(userTable[i].userName,userName)) { k=i;break; } } if(i==MaxUser) { printf(“没有找到该用户,请检查输入用户名是否正确n”); system(“pause”); return; } else { p=userTable[k].user->next; printf(“********************************************************************************n”); printf(“文件名 文件长度 文件在磁盘的起始地址 文件类型 创建时间n”); for(;p!=NULL;p=p->next) printf(“%s %d %d %s %s”,p->file->fileName,p->file->maxlength,p->file->strat,p->file->fileKind,asctime(p->file->timeinfo)); printf(“********************************************************************************n”); system(“pause”); } } void diskShow() { diskNode *p; int i=0,unusedDisk=0; printf(“***************************************************************************n”); printf(“ 盘块号 起始地址 容量(bit) 是否已被使用n”); for(p=diskHead;p!=NULL;p=p->next,i++) { if(p->useFlag==false)unusedDisk+=p->maxlength; printf(“ %d %d %d %d n”,i,p->start,p->maxlength,p->useFlag); } printf(“***************************************************************************n”); printf(“磁盘空间总容量:512*1024bit 已使用:%dbit 末使用:%dbitnn”,MaxDisk-unusedDisk,unusedDisk); system(“pause”); } void fileClose(char fileName[]) { UFD *p,*q; q=userTable[userID].user; for(p=q->next;p!=NULL;p=p->next) { if(!strcmp(p->file->fileName,fileName)) break; } if(p) { p->file->openFlag=false; printf(“%s文件已关闭n”,p->file->fileName); system(“pause”); } else { printf(“没有找到该文件,请检查输入的文件名是否正确n”); system(“pause”); } } 运行结果视图: (略) FATFS文件系统剖析2: 分析下ff.h和ff.c两个文件。先来分析ff.h中定义的几个结构体: typedef struct { BYTE fs_type;// 系统类型,为0时系统没有被挂载 BYTE drv;// 物理磁盘驱动号 BYTE csize;// 每簇的扇区数目,簇是文件数据分配的基本单位 BYTE n_fats;// 文件分配表的数目,一般为两个(一个备份fat表)//Fatfs文件系统应该是:引导扇区,文件分配表2个,根目录区,和数据区 BYTE wflag;// 文件活动窗体是否改动标志,为1要回写 BYTE fsi_flag;// 文件信息回写标志 WORD id;// 文件系统加载id号 WORD n_rootdir;// 根目录区目录项数目(针对FAT12/16,FAT32不使用)#if _MAX_SS!= 512 WORD ssize;// 每扇区多少字节 #endif #if _FS_REENTRANT _SYNC_t sobj;// 允许重入,则定义同步对象 #endif #if!_FS_READONLY DWORD last_clust;// 最新分配的簇 DWORD free_clust;// 空闲簇 DWORD fsi_sector;// 文件信息扇区(仅用于FAT32)#endif #if _FS_RPATH DWORD cdir;//使用相对路径,文件系统的当前起始路径 0(root 路径)#endif DWORD n_fatent;//文件分配表占用的扇区 n_fatent=数据簇数目+2 DWORD fsize;//每FAT表有多少个扇区 DWORD fatbase;//文件分配表开始扇区 DWORD dirbase;// 如果是FAT32,根目录开始扇区需要首先得到 DWORD database;// 数据起始扇区 DWORD winsect;// win中当前指定的扇区 BYTE win[_MAX_SS];//扇区操作缓存 } FATFS;typedef struct { FATFS* fs;// 指向的文件系统 WORD id;// 自身文件系统挂载id号 即 fs->id BYTE flag;// 文件状态 BYTE pad1;//文件在簇里面扇区偏移(0--fs->csize)DWORD fptr;//文件当前读写指针位置,当文件打开时为0 DWORD fsize;//文件大小(按字节计算) DWORD org_clust;// 文件起始簇(0 when fsize==0)DWORD curr_clust;// 文件当前操作簇 DWORD dsect;// 文件当前操作扇区 #if!_FS_READONLY DWORD dir_sect;// 包含路径入口的扇区号 BYTE* dir_ptr;// 目录入口指针 #endif #if _USE_FASTSEEK DWORD* cltbl;//指向查找映射表的簇(null on file open)#endif #if _FS_SHARE UINT lockid;// 文件锁 ID号(index of file semaphore table)#endif #if!_FS_TINY BYTE buf[_MAX_SS];// 文件读写缓存 #endif } FIL; typedef struct { FATFS* fs;// 对应的文件系统 WORD id;// 自身文件系统挂载id号 即 fs->id WORD index;// 目前读写索引号 /* Current read/write index number */ DWORD sclust;// 目录表起始簇(0:Root dir)DWORD clust;// 目前处理的簇 DWORD sect;// 目前簇里对应的扇区 BYTE* dir;//指向当前在win[]中的短文件名入口项/* Pointer to the current SFN entry in the win[] BYTE* fn;//指向短文件名(in/out){file[8],ext[3],status[1]} #if _USE_LFN WCHAR* lfn;//指向长文件名缓冲 /* Pointer to the LFN working buffer */ WORD lfn_idx;/* Last matched LFN index number(0xFFFF:No LFN)*/ #endif } DIR; typedef struct { //文件目录表项 大小=4+2+2+1+13 DWORD fsize;/* File size */ WORD fdate;/* Last modified date */ WORD ftime;/* Last modified time */ BYTE fattrib;/* Attribute */ // 文件属性 TCHAR fname[13];/* Short file name(8.3 format)*/ #if _USE_LFN //长文件名支持 TCHAR* lfname;/* Pointer to the LFN buffer */ UINT lfsize;/* Size of LFN buffer in TCHAR */ #endif } FILINFO; 结构是搞清楚了,但其里面的具体联系怎么也还收理不清楚。只有看ff.c来疏通了!里面东西还是蛮多的,咋一看,3000多行类(太多,在这里就根据我的配置,进行逐个分析吧),从头到尾,一个一个来。 首先是三个内存操作和以个字符查找处理函数,不说不解释。 然后是: static FRESULT move_window(FATFS *fs, /* File system object */ DWORD sector /* Sector number to make appearance in the fs->win[] */)/* Move to zero only writes back dirty window */ 该函数就是把指定扇区sector中的数据读到fs->win[]里面 DWORD clust2sect(/*!=0: Sector number, 0: Failed-invalid cluster# */ FATFS *fs, /* File system object */ DWORD clst /* Cluster# to be converted */)计算簇clst在对应文件系统fs里面的扇区号 DWORD get_fat(/* 0xFFFFFFFF:Disk error, 1:Internal error, Else:Cluster status */ FATFS *fs, /* File system object */ DWORD clst /* Cluster# to get the link information */)获取簇clst在文件系统fs中FAT表里面fat入口 static FRESULT dir_sdi(DIR *dj, /* Pointer to directory object */ WORD idx /* Directory index number */)根据根目录索引号idx获取相应的目录信息存储到dj结构里面 static FRESULT dir_next(/* FR_OK:Succeeded, FR_NO_FILE:End of table, FR_DENIED:EOT and could not stretch */ DIR *dj, /* Pointer to directory object */ int stretch /* 0: Do not stretch table, 1: Stretch table if needed */)获取当前目录项的索引值+1,对应的目录项信息 static FRESULT dir_find(DIR *dj /* Pointer to the directory object linked to the file name */)在目录表中查找与dj->fn相同文件名的目录项 static FRESULT create_name(DIR *dj, /* Pointer to the directory object */ const TCHAR **path /* Pointer to pointer to the segment in the path string */) 创建一个文件名为 path指向的 dj目录项 static FRESULT follow_path(/* FR_OK(0): successful,!=0: error code */ DIR *dj, /* Directory object to return last directory and found object */ const TCHAR *path /* Full-path string to find a file or directory */) 获取文件路径path对应的目录项填入dj里面 static BYTE check_fs(/* 0:The FAT BR, 1:Valid BR but not an FAT, 2:Not a BR, 3:Disk error */ FATFS *fs, /* File system object */ DWORD sect /* Sector#(lba)to check if it is an FAT boot record or not */) 读取文件系统fs的一号扇区,进行MBR 检查,文件系统类型区分 static FRESULT chk_mounted(/* FR_OK(0): successful,!=0: any error occurred */ const TCHAR **path, /* Pointer to pointer to the path name(drive number)*/ FATFS **rfs, /* Pointer to pointer to the found file system object */ BYTE chk_wp /*!=0: Check media write protection for write access */) 测试文件系统是否已挂在,如没有,就进行挂载,文件系统结构初始化 static FRESULT validate(/* FR_OK(0): The object is valid,!=0: Invalid */ FATFS *fs, /* Pointer to the file system object */ WORD id /* Member id of the target object to be checked */) 检测文件系统是否可用 如下是现配置好的文件系统引出的四个接口函数: FRESULT f_mount(//挂在一个逻辑的文件系统 BYTE vol, /* Logical drive number to be mounted/unmounted */ FATFS *fs /* Pointer to new file system object(NULL for unmount)*/)系统挂载 FRESULT f_open(FIL *fp, /* Pointer to the blank file object */ const TCHAR *path, /* Pointer to the file name */ BYTE mode /* Access mode and file open mode flags */) 文件打开,包括(真正的文件系统初始化,系统检测) FRESULT f_read(FIL *fp, /* Pointer to the file object */ void *buff, /* Pointer to data buffer */ UINT btr, /* Number of bytes to read */ UINT *br /* Pointer to number of bytes read */)文件读 FRESULT f_close(FIL *fp /* Pointer to the file object to be closed */)文件关闭 转自博客,供大家相互交流! 实验5 文件系统 :Linux文件管理 1.实验目的 (1)掌握Linux提供的文件系统调用的使用方法;(2)熟悉文件和目录操作的系统调用用户接口; (3)了解操作系统文件系统的工作原理和工作方式。2.实验内容 (1)利用Linux有关系统调用函数编写一个文件工具filetools,要求具有下列功能: *********** 0.退出 1.创建新文件 2.写文件 3.读文件 4.复制文件 5.修改文件权限 6.查看文件权限 7.创建子目录 8.删除子目录 9.改变当前目录到指定目录 10.链接操作 *********** 代码: #include int choose; int suliangjin=1; menu(); scanf(“%d”,&choose); while(choose!=0) { switch(choose) { case 1:openfile();break; case 2:writefile();break; case 3:readfile();break; case 4:copyfile();break; case 5:chmd();break; case 6:ckqx();break; case 7:cjml();break; case 8:scml();break; case 9:ggml();break; case 10:ylj();break; } menu(); scanf(“%d”,&choose); } return 0;} void menu(void){ printf(“文件系统n”); printf(“1.创建新文件n”); printf(“2.写文件n”); printf(“3.读文件n”); printf(“4.复制文件n”); printf(“5.修改文件权限n”); printf(“6.查看文件权限n”); printf(“7.创建子目录n”); printf(“8.删除子目录n”); printf(“9.改变目前目录到指定目录n”); printf(“10.链接操作n”); printf(“0.退出n”); printf(“请输入您的选择...n”);} void openfile(void){ int fd; if((fd=open(“/tmp/hello.c”,O_CREAT|O_TRUNC|O_RDWR,0666))<0) perror(“open”); else printf(“open file:hileo.c %dn”,fd); if(close(fd)<0) perror(“close”); else printf(“Close hello.cn”);} void writefile(void){ int fd,size,len; char *buf=“Hello!I'm writing to this file!”; len=strlen(buf); if((fd=open(“/tmp/hello.c”,O_CREAT|O_TRUNC|O_RDWR,0666))<0) perror(“open”); else printf(“open file:hileo.c %dn”,fd); if((size=write(fd,buf,len))<0) perror(“write”); else printf(“Write:%sn”,buf); if(close(fd)<0) perror(“close”); else printf(“Close hello.c n”);} void readfile(void){ int fd,size; char b[10]; if((fd=open(“/tmp/hello.c”,O_CREAT|O_TRUNC|O_RDWR,0666))<0) perror(“open”); else printf(“open file:hileo.c %dn”,fd); lseek(fd,0,SEEK_SET); if((size=read(fd,b,10))<0) perror(“read”); else printf(“read from file:%sn”,b); if(close(fd)<0) perror(“close”); else printf(“Close hello.cn”);} void copyfile(void){ if(fork()==0) execlp(“/bin/cp”,“cp”,“/tmp/hello.c”,“/tmp/he.c”,NULL); else wait(0); printf(“将hello.c复制he.c”);} void chmd(void){ int a; printf(“1.文件主可读可写可执行n”); printf(“2.文件主可读n”); printf(“3.文件主可写n”); printf(“4.文件主可执行n”); printf(“请输入您的选项n”); scanf(“%d”,&a); switch(a) { case 1:chmod(“/tmp/hello.c”,S_IRWXU);printf(“ok!n”);break; case 2:chmod(“/tmp/hello.c”,S_IRUSR);printf(“ok!n”);break; case 3:chmod(“/tmp/hello.c”,S_IWUSR);printf(“ok!n”);break; case 4:chmod(“/tmp/hello.c”,S_IXUSR);printf(“ok!n”);break; default:printf(“您选择有误n”); } } void ckqx(void){ char *path=“/bin/ls”; char *argv[4]={“ls”,“-l”,NULL}; if(fork()==0) execv(path,argv); else wait(0);} void cjml(void){ if(mkdir(“/tmp/a”,S_IRWXU)<0) perror(“Mkdir”); else printf(“创建成功n”);} void scml(void){ if(rmdir(“/tmp/a”)<0) perror(“Rmdir”); else printf(“删除成功n”);} void ggml(void){ if(chdir(“/tmp/bc”)<0) perror(“chdir”); else printf(“更改目录成功n”);} void ylj(void){ if(link(“hello.c”,“h.c”)<0) perror(“Link”); else printf(“建立硬连接n”);} 打开文件: 写文件: 读文件: 复制文件: 修改权限: 查看权限: 创建目录: 删除目录: 更改目录: 硬连接: 问题解决方案: 1.在复制文件时用execlp函数,虽然有复制成功但是他就跳出整个程序,这就是一个缺陷。后来我在execlp前面加if(fork)()==0)就可以咯 2.硬连接不成功,老是抛出错误信息,后来发现原来是因为我的代码出错,还有我之前已经更改了目录所以就会经常报错 3.到现在还不知道为什么我读出来的是乱码情解决 实验心得体会: 通过这次实验掌握Linux提供的文件系统调用的使用方法;熟悉文件和目录操作的调用用户接口,了解操作系统文件系统的工作原理和工作方式。第四篇:FATFS文件系统剖析2
第五篇:文件系统 :Linux文件管理