第一篇:操作系统课程设计 为LINUX 设计一个简单的二级文件系统 java实现界面
仲恺农业工程学院
课
程
设
计
为LINUX 设计一个简单的二级文件系统
姓
名
菜鸟程序员
院(系)
计算机科学与工程学院 专业班级 学
号
指导教师
职
称
课程设计日期 2011年 6月2 日至7月1日
目 录
1题目分析..........................................................1 2算法设计..........................................................1 2.1 用户登录模块..................................................1 2.2 新建目录模块..................................................2 2.3新建文件模块..................................................3 2.4 删除文件模块..................................................4 2.5 读取文件模块..................................................5 3 设计实现..........................................................6 3.1登录界面外观布局..............................................6 3.2树状显示目录..................................................7 3.3新建目录实现主要代码:.......................................10 3.4新建文件实现.................................................12 3.5删除文件实现.................................................14 3.6读取文件实现.................................................16 4设计总结.........................................................17 5参考文献.........................................................18
1题目分析
为Linux设计一个简单的二级文件系统,可以实现用户登录、列出文件目录、创建目录、创建文件、删除目录、删除文件、读取文件的功能。本次设计采用的开发语言是Java,通过Java来实现整体布局和实现相关的功能。
2算法设计
本次二级文件系统主要分为五大模块,分别是用户登录模块、新建目录模块、新建文件模块、删除文件模块和读取文件模块。用户登录成功后才可以进行其他模块的操作。
2.1 用户登录模块
用户登录模块要求用户输入账号与密码,当输入正确后进入主视图并能进行其他模块操作,否则提示账号密码错误并要求用户重新输入(默认的账号和密码都是“123”)。用户登录模块流程图如图1所示。
开始输入账号和密码账号和密码都正确?否是显示默认目录的所有文件与目录提示输入错误结束 图1 用户登录模块流程图
2.2 新建目录模块
新建目录模块是根据用户鼠标右击时选择到的节点来确定节点的名字与路径,然后判断该节点是否可以拥有子节点,若拥有则根据用户输入的目录名称新建一个目录,否则提示不能新增目录。新建目录模块流程图如图2所示。
开始获得右击时选择到的节点的路径与名字被选择的节点是否可以拥有子节点?否是用户输入新建目录的名字提示不能创建目录在本地硬盘新建一文件夹,在树型视图新增一节点结束 图2 新建目录流程图
2.3新建文件模块
新建文件模块是根据用户鼠标右击时选择到的节点来确定节点的名字与路径,然后判断该节点是否可以拥有子节点,若拥有则根据用户输入的文件名称新建一个文件,否则提示不能新增文件。新建文件模块流程图如图3所示。
开始获得右击时选择到的节点的路径与名字被选择的节点是否可以拥有子节点?否是用户输入新建文件的名字提示不能创建文件在本地硬盘新建改文件,在树型视图新增一节点结束 图3 新建文件流程图
2.4 删除文件模块
删除文件模块是根据用户鼠标右击时选择到的节点来确定要删除节点的名字与路径,然后判断该节点是目录还是文件。若是文件则直接删除文件,若是目录则进入该目录再删除其全部文件。删除文件模块流程图如图4所示。
开始获得右击时选择到的节点的路径与名字在树状视图上删除该节点否该节点是一目录?是进入该目录并遍历所有文件删除该文件删除所有被遍历的文件结束 图4 删除文件模块流程图
2.5 读取文件模块
读取文件模块是根据FileDialog类中事先设定的默认路径而打开一个选择对话框,然后根据用户选择的文件而获取文件的名字与路径。最后通过输入流而把读取到的数据显示在一个文本域中。读取文件流程图如图5所示。
开始新建一个空的文本区域生成FileDialog选择框根据用户的选择而获得文件的路径和名字运用输入输出流读取文件的数据把读取到的数据显示到文本域中结束 图5 读取文件模块流程图 设计实现
3.1登录界面外观布局
登录界面主要代码:
JLabel labelID=null,labelPassword=null,title=null;JTextField id,password;JButton conform=new JButton(“确认”);JButton cancle=new JButton(“取消”);LoginWindow(){ init();this.setTitle(“登录界面”);this.setBounds(400,200,550,400);this.setResizable(false);
this.setVisible(true);
}
void init(){
this.setLayout(null);
labelID=new JLabel(“请输入账号:”);labelID.setBounds(50, 100, 100, 30);this.add(labelID);
labelPassword=new JLabel(“请输入密码:”);labelPassword.setBounds(50, 200, 100, 30);this.add(labelPassword);
id=new JTextField(20);id.setBounds(170, 100, 300,30);this.add(id);
password=new JTextField(20);password.setBounds(170, 200, 300, 30);this.add(password);title=new JLabel(“登录界面”);conform.setBounds(100, 280, 80, 30);cancle.setBounds(250, 280, 80, 30);
conform.addActionListener(new LoginListener());cancle.addActionListener(new LoginListener());
this.add(conform);this.add(cancle);} 登录界面如图6所示
图6 登录界面
3.2树状显示目录
登录成功后显示默认路径的树状文件目录的主要代码:
void getRoot(DefaultMutableTreeNode superroot, File f){
File files[] = f.listFiles();
for(int i = 0;i < files.length;i++){
DefaultMutableTreeNode de = new DefaultMutableTreeNode(files[i].getName());
if(files[i].isDirectory()){
de.setAllowsChildren(true);
} else {
de.setAllowsChildren(false);
System.out.println(“不是目录的有:” + de.toString());
}
superroot.add(de);
} }
private class TreeListener implements TreeExpansionListener { // 重写两个方法
public void treeCollapsed(TreeExpansionEvent event){
}
public void treeExpanded(TreeExpansionEvent event){
DefaultMutableTreeNode node =(DefaultMutableTreeNode)(event
.getPath()).getLastPathComponent();
if(node.getChildCount()== 0){
DefaultMutableTreeNode originalNode = node;
String fileName = node.toString();
while(node.getParent()!= null){
node =(DefaultMutableTreeNode)node.getParent();
fileName = node.toString()+ “" + fileName;System.out.println(”当前展开路径名“ + fileName);
} if(originalNode!= null){
File f = new File(fileName);
if(f.isDirectory()){
File files[] = f.listFiles();
if(files!= null)
for(int i = 0;i < files.length;i++){
DefaultMutableTreeNode dmtn = new DefaultMutableTreeNode(files[i].getName());
if(files[i].isDirectory())
dmtn.setAllowsChildren(true);
else
dmtn.setAllowsChildren(false);
dtm.insertNodeInto(dmtn, originalNode,originalNode.getChildCount());
}
}
}
} }
树状目录显示如图7所示:
图7 树状显示目录
3.3新建目录实现主要代码:
private class NewMenuAction implements ActionListener {
public void actionPerformed(ActionEvent e){
TreePath path = tree.getSelectionPath();
MutableTreeNode node =(MutableTreeNode)path
.getLastPathComponent();
DefaultTreeModel model =(DefaultTreeModel)tree.getModel();
if(node.getAllowsChildren()){
String Name = JOptionPane.showInputDialog(null, ”创建目录名称:“);
if(!Name.equals(”“)){ MutableTreeNode newNode = new
DefaultMutableTreeNode(Name);// 建立新节点
1);
+ Name);
tree.fireTreeExpanded(path);model.insertNodeInto(newNode, node, 0);String fullPath = ”“;
for(Object obj : path.getPath()){ String str = obj.toString();if(str.endsWith(”“))
str = str.substring(0, str.length()1);if(fullPath.equals(”“))
fullPath += str;else
fullPath += ”“ + str;} String FileName = JOptionPane.showInputDialog(null, ”创建文件名称:“);
if(!FileName.equals(null)){ File f = new File(fullPath + ”“ + FileName);try {
f.createNewFile();} catch(IOException e1){
e1.printStackTrace();} } else { JOptionPane.showMessageDialog(null, ”不能添加文件!“);return;
}
}
} }
新建文件如图9所示,图9 新建文件
3.5删除文件实现
删除文件主要代码:
private class DeleteAction implements ActionListener{
public void actionPerformed(ActionEvent e){
TreePath tp = tree.getSelectionPath();
DefaultMutableTreeNode node =(DefaultMutableTreeNode)tp.getLastPathComponent();
DefaultTreeModel dtm =(DefaultTreeModel)tree.getModel();
dtm.removeNodeFromParent(node);
String fullPath = ”“;
for(Object obj : tp.getPath()){
String str = obj.toString();
if(str.endsWith(”“))
str = str.substring(0, str.length()-1);
if(fullPath.equals(”“))
fullPath += str;
else
fullPath += ”“ + str;
}
File currentFile = new File(fullPath);
if(currentFile.isFile())
currentFile.delete();
else
deleteDir(currentFile);
} } public static boolean deleteDir(File dir){
if(dir.isDirectory()){
String[] subDir = dir.list();
for(String s : subDir){
deleteDir(new File(dir, s));
}
}
return dir.delete();}
删除文件如图10所示:
图10 删除文件
3.6读取文件实现
读取文件主要代码: void readFile(){
fileDialog = new JFileChooser(”F:“);
int state = fileDialog.showOpenDialog(null);
if(state == JFileChooser.APPROVE_OPTION){
try {
File dir = fileDialog.getCurrentDirectory();
String name = fileDialog.getSelectedFile().getName();File file = new File(dir, name);// 创建一新文件
fw = new FileReader(file);
br = new BufferedReader(fw);
String s = null;
this.setTitle(name);
jta.setText(” “);// 清空文本区的内容
while((s = br.readLine())!= null){
jta.append(s + ”n");
}
br.close();
} catch(Exception e1){
e1.printStackTrace();
}
} } 读取文件如图11所示:
图11 读取文件
4设计总结
对于本次操作系统课程设,由于对树状显示目录这样面的内容比较陌生,刚起步阶段花了很大时间去查阅各种资料。当完成设计时,感觉掌握了以前学到的知识,并且还对操作系统应用有了更深入的认识。比如对树的展示有了很好的学习,对二级文件系统也有了很好的了解,熟练Java布局的使用,如何解决实现里面功能的各种问题。本次设计集树、监听器、布局、输入输出流、文件系统这几方面的知识而成,具有一定挑战性。
5参考文献
[1] 李刚.疯狂Java讲义.电子工业出版社出版社,2008.[2] 耿祥义,张跃平.Java面向对象程序设计.清华大学出版社出版社,2009.
第二篇:为LINUX 设计一个简单的二级文件系统
#include
#define MEM_D_SIZE 1024*1024
//总磁盘空间为1M #define DISKSIZE 1024
//磁盘块的大小1K #define DISK_NUM 1024 //磁盘块数目1K #define FATSIZE DISK_NUM*sizeof(struct fatitem)//FAT表大小 #define ROOT_DISK_NO FATSIZE/DISKSIZE+1
//根目录起始盘块号
#define ROOT_DISK_SIZE sizeof(struct direct)//根目录大小 #define DIR_MAXSIZE 1024 //路径最大长度为1KB #define MSD
//最大子目录数5 #define MOFN 5
//最大文件深度为5 #define MAX_WRITE 1024*128 //最大写入文字长度128KB
struct fatitem /* size 8*/ {
int item;/*存放文件下一个磁盘的指针*/
char em_disk;/*磁盘块是否空闲标志位 0 空闲*/ };
struct direct
{
/*-----文件控制快信息-----*/
struct FCB
{
char name[9];/*文件/目录名 8位*/
char property;/*属性 1位目录 0位普通文件*/
int size;
/*文件/目录字节数、盘块数)*/
int firstdisk;/*文件/目录 起始盘块号*/
int next;
/*子目录起始盘块号*/
int sign;
/*1是根目录 0不是根目录*/
}directitem[MSD+2];
};
struct opentable
{
struct openttableitem
{
char name[9];/*文件名*/
int firstdisk;/*起始盘块号*/
int size;/*文件的大小*/
}openitem[MOFN];
int cur_size;/*当前打文件的数目*/ };
struct fatitem *fat;
/*FAT表*/ struct direct *root;
/*根目录*/
struct direct *cur_dir;
/*当前目录*/
struct opentable u_opentable;/*文件打开表*/ int fd=-1;
/*文件打开表的序号*/
char *bufferdir;
/*记录当前路径的名称*/ char *fdisk;
/*虚拟磁盘起始地址*/
void initfile();void
format();void enter();void
halt();
int create(char *name);int
open(char *name);int close(char *name);
int write(int fd,char *buf,int len);int read(int fd,char *buf);int
del(char *name);int mkdir(char *name);int rmdir(char *name);void dir();
int cd(char *name);void print();void show();
void initfile(){
fdisk =(char *)malloc(MEM_D_SIZE*sizeof(char));/*申请 1M空间*/
format();
}
void format(){
int i;
FILE *fp;
fat =(struct fatitem *)(fdisk+DISKSIZE);/*计算FAT表地址,引导区向后偏移 1k)*/
/*-----初始化FAT表------------*/
fat[0].item=-1;/*引导块*/
fat[0].em_disk='1';
for(i=1;i { fat[i].item=i+1; fat[i].em_disk='1'; } fat[ROOT_DISK_NO].item=-1;/*存放根目录的磁盘块号*/ fat[ROOT_DISK_NO].em_disk='1'; for(i=ROOT_DISK_NO+1;i { fat[i].item =-1; fat[i].em_disk = '0'; } /*----------------*/ root =(struct direct *)(fdisk+DISKSIZE+FATSIZE);/*根目录的地址*/ /*初始化目录*/ /*---------指向当前目录的目录项---------*/ root->directitem[0].sign = 1; root->directitem[0].firstdisk = ROOT_DISK_NO; strcpy(root->directitem[0].name,“.”); root->directitem[0].next = root->directitem[0].firstdisk; root->directitem[0].property = '1'; root->directitem[0].size = ROOT_DISK_SIZE; /*-------指向上一级目录的目录项---------*/ root->directitem[1].sign = 1; root->directitem[1].firstdisk = ROOT_DISK_NO; strcpy(root->directitem[1].name,“..”); root->directitem[1].next = root->directitem[0].firstdisk; root->directitem[1].property = '1'; root->directitem[1].size = ROOT_DISK_SIZE; if((fp = fopen(“disk.dat”,“wb”))==NULL) { printf(“Error:n Cannot open file n”); return; } for(i=2;i { root->directitem[i].sign = 0; root->directitem[i].firstdisk =-1; strcpy(root->directitem[i].name,“"); root->directitem[i].next =-1; root->directitem[i].property = '0'; root->directitem[i].size = 0; } if((fp = fopen(”disk.dat“,”wb“))==NULL) { printf(”Error:n Cannot open file n“); return; } if(fwrite(fdisk,MEM_D_SIZE,1,fp)!=1)/*把虚拟磁盘空间保存到磁盘文件中*/ { printf(”Error:n File write error!n“); } fclose(fp); } void enter(){ FILE *fp; int i; fdisk =(char *)malloc(MEM_D_SIZE*sizeof(char));/*申请 1M空间*/ if((fp=fopen(”disk.dat“,”rb“))==NULL) { printf(”Error:nCannot open filen“); return; } if(!fread(fdisk,MEM_D_SIZE,1,fp))/*把磁盘文件disk.dat 读入虚拟磁盘空间(内存)*/ { printf(”Error:nCannot read filen“); exit(0); } fat =(struct fatitem *)(fdisk+DISKSIZE);/*找到FAT表地址*/ root =(struct direct *)(fdisk+DISKSIZE+FATSIZE);/*找到根目录地址*/ fclose(fp); /*--------------初始化用户打开表------------------*/ for(i=0;i { strcpy(u_opentable.openitem[i].name,”“); u_opentable.openitem[i].firstdisk =-1; u_opentable.openitem[i].size = 0; } u_opentable.cur_size = 0; cur_dir = root;/*当前目录为根目录*/ bufferdir =(char *)malloc(DIR_MAXSIZE*sizeof(char)); strcpy(bufferdir,”Root:“); } void halt(){ FILE *fp; int i; if((fp=fopen(”disk.dat“,”wb“))==NULL) { printf(”Error:nCannot open filen“); return; } if(!fwrite(fdisk,MEM_D_SIZE,1,fp))/*把虚拟磁盘空间(内存)内容读入磁盘文件disk.dat */ { printf(”Error:nFile write error!n“); } fclose(fp); free(fdisk); free(bufferdir); return;} int create(char *name){ int i,j; if(strlen(name)>8)/*文件名大于 8位*/ return(-1); for(j=2;j { if(!strcmp(cur_dir->directitem[j].name,name)) break; } if(j /*文件已经存在*/ return(-4); for(i=2;i { if(cur_dir->directitem[i].firstdisk==-1) break; } if(i>=MSD+2)/*无空目录项*/ return(-2); if(u_opentable.cur_size>=MOFN)/*打开文件太多*/ return(-3); for(j=ROOT_DISK_NO+1;j { if(fat[j].em_disk=='0') break; } if(j>=DISK_NUM) return(-5); fat[j].em_disk = '1';/*将空闲块置为已经分配*/ /*-----------填写目录项-----------------*/ strcpy(cur_dir->directitem[i].name,name); cur_dir->directitem[i].firstdisk = j; cur_dir->directitem[i].size = 0; cur_dir->directitem[i].next = j; cur_dir->directitem[i].property = '0'; /*--*/ fd = open(name); return 0; } int open(char *name){ int i, j; for(i=2;i { if(!strcmp(cur_dir->directitem[i].name,name)) break; } if(i>=MSD+2) return(-1); /*--------是文件还是目录-----------------------*/ if(cur_dir->directitem[i].property=='1') return(-4); /*--------文件是否打开-----------------------*/ for(j=0;j { if(!strcmp(u_opentable.openitem[j].name,name)) break; } if(j return(-2); if(u_opentable.cur_size>=MOFN)/*文件打开太多*/ return(-3); /*--------查找一个空闲用户打开表项-----------------------*/ for(j=0;j { if(u_opentable.openitem[j].firstdisk==-1) break; } /*--------------填写表项的相关信息------------------------*/ u_opentable.openitem[j].firstdisk = cur_dir->directitem[i].firstdisk; strcpy(u_opentable.openitem[j].name,name); u_opentable.openitem[j].size = cur_dir->directitem[i].size; u_opentable.cur_size++; /*----------返回用户打开表表项的序号--------------------------*/ return(j);} int close(char *name){ int i; for(i=0;i { if(!strcmp(u_opentable.openitem[i].name,name)) break; } if(i>=MOFN) return(-1); /*-----------清空该文件的用户打开表项的内容---------------------*/ strcpy(u_opentable.openitem[i].name,”"); u_opentable.openitem[i].firstdisk =-1; u_opentable.openitem[i].size = 0; u_opentable.cur_size--; return 0;} int write(int fd, char *buf, int len){ char *first; int item, i, j, k; int ilen1, ilen2, modlen, temp; /*----------用 $ 字符作为空格 # 字符作为换行符-----------------------*/ char Space = 32; char Endter= 'n'; for(i=0;i { if(buf[i] == '$') buf[i] = Space; else if(buf[i] == '#') buf[i] = Endter; } /*----------读取用户打开表对应表项第一个盘块号-----------------------*/ item = u_opentable.openitem[fd].firstdisk; /*-------------找到当前目录所对应表项的序号-------------------------*/ for(i=2;i { if(cur_dir->directitem[i].firstdisk==item) break; } temp = i;/*-存放当前目录项的下标-*/ /*------找到的item 是该文件的最后一块磁盘块-------------------*/ while(fat[item].item!=-1){ item =fat[item].item;/*-查找该文件的下一盘块--*/ } /*-----计算出该文件的最末地址-------*/ first = fdisk+item*DISKSIZE+u_opentable.openitem[fd].size%DISKSIZE; /*-----如果最后磁盘块剩余的大小大于要写入的文件的大小-------*/ if(DISKSIZE-u_opentable.openitem[fd].size%DISKSIZE>len) { strcpy(first,buf); u_opentable.openitem[fd].size = u_opentable.openitem[fd].size+len; cur_dir->directitem[temp].size = cur_dir->directitem[temp].size+len; } else { for(i=0;i<(DISKSIZE-u_opentable.openitem[fd].size%DISKSIZE);i++) {/*写一部分内容到最后一块磁盘块的剩余空间(字节)*/ first[i] = buf [i]; } /*-----计算分配完最后一块磁盘的剩余空间(字节)还剩下多少字节未存储-------*/ ilen1 = len-(DISKSIZE-u_opentable.openitem[fd].size%DISKSIZE); ilen2 = ilen1/DISKSIZE; modlen = ilen1%DISKSIZE; if(modlen>0) ilen2 = ilen2+1;/*--还需要多少块磁盘块-*/ for(j=0;j { for(i=ROOT_DISK_NO+1;i { if(fat[i].em_disk=='0') break; } if(i>=DISK_NUM)/*--如果磁盘块已经分配完了-*/ return(-1); first = fdisk+i*DISKSIZE;/*--找到的那块空闲磁盘块的起始地址-*/ if(j==ilen2-1)/*--如果是最后要分配的一块-*/ { for(k=0;k first[k] = buf[k]; } else/*-如果不是要最后分配的一块--*/ { for(k=0;k first[k] =buf[k]; } fat[item].item = i;/*--找到一块后将它的序号存放在上一块的指针中-*/ fat[i].em_disk = '1';/*--置找到的磁盘快的空闲标志位为已分配-*/ fat[i].item =-1;/*--它的指针为-1(即没有下一块)-*/ } /*--修改长度-*/ u_opentable.openitem[fd].size = u_opentable.openitem[fd].size+len; cur_dir->directitem[temp].size = cur_dir->directitem[temp].size+len; } return 0;} int read(int fd, char *buf){ int len = u_opentable.openitem[fd].size; char *first; int i, j, item; int ilen1, modlen; item = u_opentable.openitem[fd].firstdisk; ilen1 = len/DISKSIZE; modlen = len%DISKSIZE; if(modlen!=0) ilen1 = ilen1+1;/*--计算文件所占磁盘的块数-*/ first = fdisk+item*DISKSIZE;/*--计算文件的起始位置-*/ for(i=0;i { if(i==ilen1-1)/*--如果在最后一个磁盘块-*/ { for(j=0;j buf[i*DISKSIZE+j] = first[j]; } else /*--不在最后一块磁盘块-*/ { for(j=0;j buf[i*DISKSIZE+j] = first[j]; item = fat[item].item;/*-查找下一盘块-*/ first = fdisk+item*DISKSIZE; } } return 0;} int del(char *name){ int i,cur_item,item,temp; for(i=2;i { if(!strcmp(cur_dir->directitem[i].name,name)) break; } }