import java.awt.BorderLayout;
import java.awt.FlowLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.JTextArea;
import javax.swing.JTextField;
public class Java extends JFrame implements ActionListener {
JTable table;
JScrollPane sp1,sp2; //设置两个带有滚动条的面板
JTextArea ta;
JLabel l1,l2,l3,l4,l5; //标签
JTextField tf1,tf2,tf3; //文本框
JButton b1,b2,b3,b4; //按钮
JPanel p1,p2,p3,p4,p5,p6,p7; //面板容器
String data[][]; //二组数组data[i][j]记录位示图的使用情况
String column[];
int sp [];//存放相对可用块
int used[];//存放相对已用块
int A,H;//A为可用块,H为已用块
public static void main(String [] args){
new Java();
}
//功能:初始化,随意分配0和1
public void init() {
int k;
for(int i=0;i<32;i++)
for(int j=0;j<16;j++) {
k = (int)(Math. random()*2);//0与1两数字中进行随机
data[i][j]=""+k;
table.setValueAt(""+k,i,j);
}
}
public Java() {
// TODO Auto-generated constructor stub
super("位示图管理磁盘空间的分配与回收算法模拟实现");
data=new String[32][16];
column =new String[16];//16个列
sp=new int[512];
used=new int[512];
A=0; //可用块为0
H=0; //已用块为0
for(int i=0;i<16;i++) {
column[i]=""+i;
}
table = new JTable(data,column);
//第一个带有滚动条的面板
sp1 = new JScrollPane(table);
tf1 = new JTextField(6); //tf1 文本框
tf2 = new JTextField(6); //tf2 文本框
tf3 = new JTextField(8); //tf3 文本框
ta = new JTextArea(10,20);
//第二个带有滚动条的面板
sp2 = new JScrollPane(ta);
p1 = new JPanel(new BorderLayout());
p2 = new JPanel(new FlowLayout());
p3 = new JPanel(new BorderLayout());
p4 = new JPanel(new FlowLayout());
p5 = new JPanel(new FlowLayout());
p6 = new JPanel(new BorderLayout());
p7 = new JPanel(new FlowLayout());
l1 = new JLabel("位示图"); //标签——位示图
b1 = new JButton("位示图初始化"); //按钮——位示图初始化
b1. addActionListener(this);
b2 = new JButton("回收全部磁盘块"); //按钮——回收全部磁盘块
b2. addActionListener(this);
p2. add(b1);
p2. add(b2);
p1. add(l1, "North");
p1. add(sp1, "Center");
p1. add(p2 ,"South");
l2 = new JLabel("运行状况: ");
l5 = new JLabel("空闲块数量: ");
p7. add(l5);
p7. add(tf3);
p3. add(l2, "North");
p3. add(p7,"South");
p3. add(sp2,"Center");
l3 = new JLabel("请输入需要分配的块数: "); //标签——请输入需要分配的块数
l4 = new JLabel("请输入要回收的盘块号: "); //标签——请输入要回收的盘块号
b3 = new JButton("确认分配"); //按钮——确认分配
b3.addActionListener(this);
b4= new JButton("确认回收"); //按钮——确认回收
b4. addActionListener(this);
p4. add(l3);
p4. add(tf1);
p4. add(b3);
p5. add(l4);
p5. add(tf2);
p5. add(b4);
p6. add(p4 ,"North");
p6. add(p5, "Center");
this.setLayout(new BorderLayout());
this. add(p1, "West");
this. add(p3,"Center");
this. add(p6, "South");
this. pack();
this. setVisible(true);
}
/*
* 转换公式的四种情况
1.行列号从0开始,盘块号从0开始
分配时,行列号转换为盘块号
盘块号 = 行号 ∗ 行位数 + 列号
回收时,盘块号转换为行列号:
行号 = 盘块号 / 行位数
列号 = 盘块号 % 行位数
2.行列号从0开始,盘块号从1开始
分配时,相对于第一种情况,计算后盘块号再加一
盘块号 = 行号 ∗ 行位数 + 列号 + 1
回收时,相对于第一种情况,计算前盘块号先减一
行号 = (盘块号−1) / 行位数
列号 = (盘块号 − 1) % 行位数
3.行列号从1开始,盘块号从0开始
分配时,相对于第一种情况,计算前行列号先减一
盘块号 = (行号 − 1) ∗ 行位数 + 列号 − 1
回收时,相对于第一种情况,计算后行列号再加一
行号 = 盘块号 / 行位数 + 1
列号 = 盘块号 % 行位数 + 1
4.行列号从1开始,盘块号从1开始
分配时,相对于第一种情况,计算前行列号先减一,计算后盘块号再加一
盘块号 = (行号 − 1) * 行位数 + (列号 − 1) + 1
即,盘块号 = (行号 - 1) * 行位数 + 列号
回收时,相对于第一种情况,计算前盘块号先减一,计算后行列号再加一
行号 = (盘块号 — 1) / 行位数 + 1
列号 = (盘块号 —1) % 行位数 + 1
* */
//功能:得出可用块号与不可用块号的集合
public void getavail()
{
//a表示柱面号,b表示磁道号,c表示扇区号
int a;
int b=0,c=0;
A= 0;
H=0;
for(int i=0;i<32;i++)
for(int j=0;j<16;j++) {
if(data[i][j].equals("0")) {
a=i*16+j;//得到相对块号,相对块号=字号*16+位号
sp[b]=a;//写入可用块集合
A++;
b++;
}else{
a=i*16+j;//得到相对块号
used[c]=a;
H++;
c++;//写入不可用块号集合
}
}
}
//全部收回磁盘块
public void allrec(){
ta.setText("");
String str= "收回结果:\n";
for(int i=0;i<H;i++) {
int a = used[i]/16;
int b = used[i]%16/4;
int c = used[i]%16%4;
data[a][4*b+c]="0";
table.setValueAt("0",a,4*b+c);//位示图相应位置零
str+="柱面"+a+"--磁道"+b+"--扇区"+c+"--盘块号"+used[i]+"\n";
used[i]=0;//位示图相应位置置零
}
for(int i=0;i<32;i++)
for(int j=0;j<16;j++)
{
table.setValueAt("0",i,j);
}
H=0;
getavail();
ta.append(str);
}
//按钮的监听器
@Override
public void actionPerformed(ActionEvent e) {
// TODO Auto-generated method stub
if(e.getSource()==b1) {
init();
getavail();
String str6=""+A;
ta.append("初始化完成\n");
tf3.setText(str6);
}
else if(e.getSource()==b2) {
if(A==512) {
ta.setText("");
String str7="没有资源可回收";
ta.append(str7);
}else {
allrec();
}
String str8=""+A;
tf3.setText(str8);
}
else if(e.getSource()==b3) {
int n;
System.out.println(tf1.getText());
n=Integer.parseInt(tf1.getText());
tf1.setText("");
if(A<n) {
ta.setText("");
String str1="空闲块不足";
ta. append(str1);
JOptionPane.showMessageDialog(null, "空闲块不足","提示",JOptionPane.PLAIN_MESSAGE);
return;
}
else {
int j,k;
ta.setText("");
String str= "分配结果\n" ;
int x=H;
for(int i=0;i<n;i++) {
j = sp[1]/16;
k = sp[1]-j*16;
used[x+1]=sp[1];//可用块相对地址转为已用块相对地址
data[j][k]="1";
table. setValueAt("1",j,k);//将位示图对应位置写1
str+="柱面"+sp[i]/16+"--磁道"+(sp[i]%16)/4+"-- 扇区"+(sp[i]%16)%4+"--盘块号: "+sp[i]+" \n";
A--;
H++;
}
for(int t=0;t<A;t++) {
sp[t]=sp[t+n];//删除可用块中的已用块
}
ta. append(str);
}
String str2=""+A;
tf3.setText(str2);
tf1. setText("");
}
else if(e. getSource()==b4) {
int num;
num=Integer.parseInt(tf2.getText());
ta.setText("");
String str="";
int j,k=0;
int a=num/16;//柱面
int b=num%16/4;//磁道
int c=num%16%4;//扇区
if(data[a][4*b+c].equals("0")){
JOptionPane.showInternalMessageDialog(null, "不可回收空闲块","提示",JOptionPane.PLAIN_MESSAGE);
//tf2.setText(" ");
System.out.println("不可回收");
return;
}else {
data[a][4*b+c]="0";
table.setValueAt("0",a,4*b+c);
str+="柱面"+a+"磁道"+b+"扇区"+c+"盘块号"+num+"\n";
A++;
H--;
for(int i=0;i<H;i++) {
if(used[i]==num) {
k=i;
break;
}
}
for( j=k;j<H;j++)
{
used[j]=used[j+1];//将回收的块号从以用中删除
ta.append("回收结果:\n");
ta.append(str);
}
}
getavail();
String str5=""+A;
tf3.setText(str5);
tf2.setText("");
}
}
}
磁盘空间管理
于 2022-05-08 14:55:20 首次发布