├── README.md
├── 内存管理_动态分区分配方式
├── README.md
├── Resource
│ └── memory.png
├── src
│ ├── Dynamic partition allocation.html
│ └── static
│ │ ├── css
│ │ ├── range.css
│ │ └── style.css
│ │ └── js
│ │ ├── RangeSlider.js
│ │ ├── clear.js
│ │ ├── nextAssingment.js
│ │ ├── randColor.js
│ │ └── select.js
├── 动态分区分配方式模拟_设计方案报告.md
└── 动态分区分配方式模拟_设计方案报告.pdf
├── 内存管理_请求分区分配方式
├── DemandPaging.exe
├── README.md
├── src
│ └── DemandPaging.cpp
├── 请求分区分配方式模拟_设计方案报告.md
└── 请求分区分配方式模拟_设计方案报告.pdf
├── 文件管理_文件管理模拟系统
├── BitMapInfo.txt
├── CategoryInfo.txt
├── FileManageSystem.exe
├── FileManageSystem.exe.config
├── FileManageSystem.pdb
├── MyControl.dll
├── MyControl.pdb
├── MyDiskInfo.txt
├── README.md
├── Resources
│ ├── file18.png
│ ├── file25.png
│ ├── fileopen48.ico
│ ├── folder18.png
│ ├── folder25.png
│ └── icon
│ │ ├── help.ico
│ │ ├── icon.ico
│ │ └── note.ico
├── src
│ ├── Category.cs
│ ├── FCB.cs
│ ├── Form
│ │ ├── HelpForm
│ │ │ ├── HelpForm.Designer.cs
│ │ │ ├── HelpForm.cs
│ │ │ └── HelpForm.resx
│ │ ├── MainForm
│ │ │ ├── MainForm.Designer.cs
│ │ │ ├── MainForm.cs
│ │ │ └── MainForm.resx
│ │ └── NoteForm
│ │ │ ├── NoteForm.Designer.cs
│ │ │ ├── NoteForm.cs
│ │ │ └── NoteForm.resx
│ ├── Program.cs
│ └── VirtualDisk.cs
├── 工程文件整体(防丢失).rar
├── 文件管理系统_设计方案报告.md
└── 文件管理系统_设计方案报告.pdf
└── 进程管理_电梯调度
├── README.md
├── Resources
├── Button
│ ├── doordown.png
│ ├── doordown_hover.png
│ ├── doordown_pressed.png
│ ├── doorup.png
│ ├── doorup_hover.png
│ ├── doorup_pressed.png
│ ├── down.png
│ ├── down_hover.png
│ ├── down_pressed.png
│ ├── state.png
│ ├── state_down.png
│ ├── state_up.png
│ ├── up.png
│ ├── up_hover.png
│ └── up_pressed.png
├── Figure
│ └── people.png
└── Icon
│ ├── elevator.ico
│ └── icon.png
├── Src
├── dispatch.py
├── myElevator.py
└── myElevatorInterface.py
├── 电梯调度_设计方案报告.md
└── 电梯调度_设计方案报告.pdf
/README.md:
--------------------------------------------------------------------------------
1 | # 操作系统课程项目
2 |
3 | * [项目说明](#项目说明)
4 | * [进程管理-电梯调度](#进程管理-电梯调度)
5 | * [内存管理](#内存管理)
6 | * [动态分区分配方式](#动态分区分配方式)
7 | * [请求分区分配方式](#请求分区分配方式)
8 | * [文件管理-文件管理模拟系统](#文件管理-文件管理模拟系统)
9 | * [项目结构](#项目结构)
10 | * [作者](#作者)
11 |
12 | ------
13 |
14 | ## 项目说明
15 |
16 | ### 进程管理-电梯调度
17 |
18 | 1. 每个电梯里面设置必要功能键:如**数字键**、**关门键**、**开门键**、**上行键**、**下行键**、**报警键**、当前电梯的**楼层数**、**上升及下降状态**等。
19 | 2. 每层楼的每部电梯门口,应该有**上行和下行按钮**和当前**电梯状态的数码显示器**。
20 | 3. 五部电梯门口的**按钮是互联结的**,即当一个电梯按钮按下去时,其他电梯的相应按钮也就同时点亮,表示也按下去了。
21 | 4. 所有电梯初始状态都在第一层。每个电梯如果在它的上层或者下层没有相应请求情况下,则应该**在原地保持不动**。
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 | ### 内存管理
30 |
31 | #### 动态分区分配方式
32 |
33 | 假设初始态下,可用内存空间为640K,并有下列请求序列,请分别用首次适应算法和最佳适应算法进行内存块的分配和回收,并显示出每次分配和回收后的空闲分区链的情况来。
34 |
35 | | 作业1申请130K |
36 | | :-----------: |
37 | | 作业2申请 60K |
38 | | 作业3申请100k |
39 | | 作业2释放 60K |
40 | | 作业4申请200K |
41 | | 作业3释放100K |
42 | | 作业1释放130K |
43 | | 作业5申请140K |
44 | | 作业6申请 60K |
45 | | 作业7申请 50K |
46 | | 作业6释放 60K |
47 |
48 |
49 |
50 |
51 |
52 | #### 请求分区分配方式
53 |
54 | - 在模拟过程中,如果所访问指令在内存中,则显示其物理地址,并转到下一条指令;如果没有在内存中,则发生缺页,此时需要记录缺页次数,并将其调入内存。如果4个内存块中已装入作业,则需进行页面置换。
55 |
56 | - 所有320条指令执行完成后,计算并显示作业执行过程中发生的缺页率。
57 |
58 | - 置换算法可以选用FIFO或者LRU算法
59 |
60 | - 作业中指令访问次序可以按照下面原则形成:
61 |
62 | 50%的指令是顺序执行的,25%是均匀分布在前地址部分,25%是均匀分布在后地址部分
63 |
64 |
65 |
66 |
67 |
68 | ### 文件管理-文件管理模拟系统
69 |
70 | - 文件存储空间管理可采取显式链接(如FAT)或者其他方法。(即自选一种方法)
71 |
72 | - 空闲空间管理可采用位图或者其他方法。如果采用了位图,可将位图和FAT表合二为一。
73 |
74 | - 文件目录采用多级目录结构。至于是否采用索引节点结构,自选。目录项目中应包含:文件名、物理地址、长度等信息。同学可在这里增加一些其他信息。
75 |
76 | - 文件系统提供的操作:
77 |
78 | - 格式化
79 | - 创建子目录
80 | - 删除子目录
81 | - 显示目录
82 | - 更改当前目录
83 | - 创建文件
84 | - 打开文件
85 | - 关闭文件
86 | - 写文件
87 | - 读文件
88 | - 删除文件
89 |
90 |
91 |
92 |
93 |
94 |
95 |
96 | ## 项目结构
97 |
98 |
99 | 项目结构树
100 |
101 | ```
102 | ├── README.md
103 | ├── this.md
104 | ├── 进程管理_电梯调度
105 | │ ├── README.md
106 | │ ├── Resources
107 | │ │ ├── Button
108 | │ │ │ ├── doordown.png
109 | │ │ │ ├── doordown_hover.png
110 | │ │ │ ├── doordown_pressed.png
111 | │ │ │ ├── doorup.png
112 | │ │ │ ├── doorup_hover.png
113 | │ │ │ ├── doorup_pressed.png
114 | │ │ │ ├── down.png
115 | │ │ │ ├── down_hover.png
116 | │ │ │ ├── down_pressed.png
117 | │ │ │ ├── state.png
118 | │ │ │ ├── state_down.png
119 | │ │ │ ├── state_up.png
120 | │ │ │ ├── up.png
121 | │ │ │ ├── up_hover.png
122 | │ │ │ └── up_pressed.png
123 | │ │ ├── Figure
124 | │ │ │ └── people.png
125 | │ │ └── Icon
126 | │ │ ├── elevator.ico
127 | │ │ └── icon.png
128 | │ ├── Src
129 | │ │ ├── dispatch.py
130 | │ │ ├── myElevator.py
131 | │ │ └── myElevatorInterface.py
132 | │ ├── 电梯调度_设计方案报告.md
133 | │ └── 电梯调度_设计方案报告.pdf
134 | ├── 内存管理_动态分区分配方式
135 | │ ├── README.md
136 | │ ├── Resource
137 | │ │ └── memory.png
138 | │ ├── src
139 | │ │ ├── Dynamic partition allocation.html
140 | │ │ └── static
141 | │ │ ├── css
142 | │ │ │ ├── range.css
143 | │ │ │ └── style.css
144 | │ │ └── js
145 | │ │ ├── RangeSlider.js
146 | │ │ ├── clear.js
147 | │ │ ├── nextAssingment.js
148 | │ │ ├── randColor.js
149 | │ │ └── select.js
150 | │ ├── 动态分区分配方式模拟_设计方案报告.md
151 | │ └── 动态分区分配方式模拟_设计方案报告.pdf
152 | ├── 内存管理_请求分区分配方式
153 | │ ├── DemandPaging.exe
154 | │ ├── README.md
155 | │ ├── src
156 | │ │ └── DemandPaging.cpp
157 | │ ├── 请求分区分配方式模拟_设计方案报告.md
158 | │ └── 请求分区分配方式模拟_设计方案报告.pdf
159 | └── 文件管理_文件管理模拟系统
160 | ├── BitMapInfo.txt
161 | ├── CategoryInfo.txt
162 | ├── FileManageSystem.exe
163 | ├── FileManageSystem.exe.config
164 | ├── FileManageSystem.pdb
165 | ├── MyControl.dll
166 | ├── MyControl.pdb
167 | ├── MyDiskInfo.txt
168 | ├── README.md
169 | ├── Resources
170 | │ ├── file18.png
171 | │ ├── file25.png
172 | │ ├── fileopen48.ico
173 | │ ├── folder18.png
174 | │ ├── folder25.png
175 | │ └── icon
176 | │ ├── help.ico
177 | │ ├── icon.ico
178 | │ └── note.ico
179 | ├── src
180 | │ ├── Category.cs
181 | │ ├── FCB.cs
182 | │ ├── Form
183 | │ │ ├── HelpForm
184 | │ │ │ ├── HelpForm.Designer.cs
185 | │ │ │ ├── HelpForm.cs
186 | │ │ │ └── HelpForm.resx
187 | │ │ ├── MainForm
188 | │ │ │ ├── MainForm.Designer.cs
189 | │ │ │ ├── MainForm.cs
190 | │ │ │ └── MainForm.resx
191 | │ │ └── NoteForm
192 | │ │ ├── NoteForm.Designer.cs
193 | │ │ ├── NoteForm.cs
194 | │ │ └── NoteForm.resx
195 | │ ├── Program.cs
196 | │ └── VirtualDisk.cs
197 | ├── 工程文件整体(防丢失).rar
198 | ├── 文件管理系统_设计方案报告.md
199 | └── 文件管理系统_设计方案报告.pdf
200 | ```
201 |
202 |
203 |
204 |
205 | ## 关于作者
206 |
207 | | Name | 张喆 |
208 | | -------- | --------------------------------------------------- |
209 | | 学号 | 1754060 |
210 | | 指导老师 | 王冬青老师 |
211 | | 课程名称 | 操作系统 |
212 | | 上课时间 | 周三/周五 上午一二节 |
213 | | 联系方式 | [dbzdbz@tongji.edu.cn](mailto:dbzdbz@tongji.edu.cn) |
214 |
--------------------------------------------------------------------------------
/内存管理_动态分区分配方式/README.md:
--------------------------------------------------------------------------------
1 | # 内存管理 - 动态分区分配方式模拟
2 |
3 | ###### 操作系统第二次课程作业 - 动态分区分配方式模拟
4 |
5 | ## 目录
6 |
7 | - [开发环境](#开发环境)
8 | - [操作说明](#操作说明)
9 | - [项目结构](#项目结构)
10 | - [作者](#作者)
11 |
12 |
13 |
14 | ## 开发环境
15 |
16 | - **开发环境:** Windows 10
17 |
18 | - **开发软件:**
19 |
20 | 1. **Visual Studio Code** *1.34.0*
21 | 2. **WebStorm** *2019.1.1.WS-191.6707.60*
22 |
23 | - **开发语言:** html, javascript, css, jQuery
24 |
25 | - **主要引用块内容:**
26 |
27 | ```html
28 |
29 | ```
30 |
31 |
32 |
33 | ## 操作说明
34 |
35 | - 双击目录`src`下的`Dynamic partition allocation.html`文件, 并在浏览器中打开,打开后界面如下图所示
36 |
37 | 
38 |
39 | - 选择希望进行模拟的动态分区分配算法*(首次适应算法/最佳适应算法)*
40 |
41 | 
42 |
43 | - 调节滑动条改变当前内存大小*(上方模拟链式空间长度会随着滑动条滑动而动态变化)*
44 |
45 | 
46 |
47 | - 点击**下一步**进行作业调度
48 |
49 | 
50 |
51 | - 上方的模拟内存会显示每次分配和回收后的空闲分区链的情况*(不同作业的颜色不同, 以区分不同作业在内存中的位置分布情况)*
52 |
53 | 
54 |
55 | - 下方的日志信息会显示作业*申请/释放*等信息
56 |
57 | 
58 |
59 | - 点击**清空内存**会清空内存中的作业以及日志信息全部内容, 此时可再次调整内存空间大小, 并再次进行动态分区分配方式模拟
60 |
61 |
62 |
63 |
64 | ## 项目结构
65 | ```
66 | │ README.md
67 | │ 动态分区分配方式模拟_设计方案报告.md
68 | │ 动态分区分配方式模拟_设计方案报告.pdf
69 | │
70 | ├─Resource
71 | │ memory.png
72 | │
73 | └─src
74 | │ Dynamic partition allocation.html
75 | │
76 | └─static
77 | ├─css
78 | │ range.css
79 | │ style.css
80 | │
81 | └─js
82 | clear.js
83 | nextAssingment.js
84 | randColor.js
85 | RangeSlider.js
86 | select.js
87 | ```
88 |
89 |
90 |
91 | #### 作者
92 |
93 | **学号** 1754060
94 |
95 | **姓名** 张喆
96 |
97 | **指导老师** 王冬青老师
98 |
99 | **上课时间** 周三/周五 上午一二节
100 |
101 | **联系方式** *email:* doubleZ0108@gmail.com
102 |
--------------------------------------------------------------------------------
/内存管理_动态分区分配方式/Resource/memory.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/doubleZ0108/Operating-System/f00305ef02f4c4b7a92252947dcd559e7602c434/内存管理_动态分区分配方式/Resource/memory.png
--------------------------------------------------------------------------------
/内存管理_动态分区分配方式/src/Dynamic partition allocation.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 | Dynamic partition allocation
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 | 动态分区分配方式模拟
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
请选择分区分配算法
40 |
41 |
首次适应算法
42 |
43 |
44 | - 首次适应算法
45 | - 最佳适应算法
46 |
47 |
48 |
49 |
50 |
51 |
52 |
请选择内存空间大小
53 |
200
54 | K
55 |
56 |
57 |
58 |
59 |
60 |
61 |
62 |
63 |
67 |
68 |
69 |
70 |
71 |
75 |
76 |
77 |
78 |
79 |
80 |
81 | 日志信息
82 |
84 |
85 |
86 |
87 |
88 |
104 |
105 |
106 |
107 |
108 |
109 |
110 |
--------------------------------------------------------------------------------
/内存管理_动态分区分配方式/src/static/css/range.css:
--------------------------------------------------------------------------------
1 | /*去除系统默认的样式*/
2 | input[type=range] {
3 | -webkit-appearance: none;
4 | width: 300px;
5 | border-radius: 10px;
6 | /*这个属性设置使填充进度条时的图形为圆角*/
7 | }
8 |
9 | input[type=range]::-webkit-slider-thumb {
10 | -webkit-appearance: none;
11 | }
12 |
13 | /*自定义滑动控件的轨道*/
14 | input[type=range]::-webkit-slider-runnable-track {
15 | height: 15px;
16 | border-radius: 10px;
17 | /*将轨道设为圆角的*/
18 | box-shadow: 0 1px 1px #def3f8, inset 0 .125em .125em #0d1112;
19 | /*轨道内置阴影效果*/
20 | }
21 | /*原始的控件获取到焦点时,会显示包裹整个控件的边框,所以还需要把边框取消。*/
22 | input[type=range]:focus {
23 | outline: none;
24 | }
25 |
26 | input[type=range]::-webkit-slider-thumb {
27 | -webkit-appearance: none;
28 | height: 25px;
29 | width: 25px;
30 | margin-top: -5px; /*使滑块超出轨道部分的偏移量相等*/
31 | background: #ffffff;
32 | border-radius: 50%; /*外观设置为圆形*/
33 | border: solid 0.125em rgba(205, 224, 230, 0.5); /*设置边框*/
34 | box-shadow: 0 .125em .125em #3b4547; /*添加底部阴影*/
35 | }
36 |
--------------------------------------------------------------------------------
/内存管理_动态分区分配方式/src/static/css/style.css:
--------------------------------------------------------------------------------
1 | /*中部链式内存样式*/
2 | .memory {
3 | margin-top: 5%;
4 | height: 100px;
5 | width: 200px;
6 | border-top: 4px solid black;
7 | border-bottom: 4px solid black;
8 | display: flex;
9 | position: relative;
10 | }
11 |
12 | /*内存中的每一个作业*/
13 | .memory-proj {
14 | margin-top: 1px;
15 | background-color: rgb(111, 120, 172);
16 | height: 98px;
17 | width: 100px;
18 | position: absolute;
19 | }
20 |
21 |
22 | /*下拉框*/
23 | .model-box {
24 | position: relative;
25 | width: 200px;
26 | height: 30px;
27 | line-height: 30px;
28 | background-color: #fff;
29 | border: 1px solid #e4e4e4;
30 | border-radius: 3px;
31 | text-indent: 5px;
32 | }
33 |
34 | /*下拉框中待选文字*/
35 | .model-box .model-select-text {
36 | position: relative;
37 | width: 100%;
38 | height: 28px;
39 | color: #666;
40 | text-indent: 10px;
41 | font-size: 14px;
42 | cursor: pointer;
43 | user-select: none;
44 | }
45 |
46 | .model-box .model-select-text:after {
47 | position: absolute;
48 | top: 10px;
49 | right: 10px;
50 | content: '';
51 | width: 0;
52 | height: 0;
53 | border-width: 10px 8px 0;
54 | border-style: solid;
55 | border-color: #666 transparent transparent;
56 | }
57 |
58 | .model-box .model-select-option {
59 | position: absolute;
60 | top: 30px;
61 | left: -1px;
62 | display: none;
63 | list-style: none;
64 | border: 1px solid #e4e4e4;
65 | border-top: none;
66 | padding: 0;
67 | margin: 0;
68 | width: 100%;
69 | z-index: 99;
70 | background-color: #fff;
71 | }
72 |
73 | .model-box .model-select-option li {
74 | height: 28px;
75 | line-height: 28px;
76 | color: #333;
77 | font-size: 14px;
78 | margin: 0;
79 | padding: 0;
80 | cursor: pointer;
81 | }
82 |
83 | .model-box .model-select-option li:hover {
84 | background-color: #f3f3f3;
85 | }
86 |
87 | .model-box .model-select-option li.seleced {
88 | background-color: #f3f3f3;
89 | }
90 |
91 |
92 | .disable {
93 | pointer-events: none;
94 | }
--------------------------------------------------------------------------------
/内存管理_动态分区分配方式/src/static/js/RangeSlider.js:
--------------------------------------------------------------------------------
1 | $.fn.RangeSlider = function (cfg) {
2 | this.sliderCfg = {
3 | min: cfg && !isNaN(parseFloat(cfg.min)) ? Number(cfg.min) : null,
4 | max: cfg && !isNaN(parseFloat(cfg.max)) ? Number(cfg.max) : null,
5 | step: cfg && Number(cfg.step) ? cfg.step : 1,
6 | callback: cfg && cfg.callback ? cfg.callback : null
7 | };
8 |
9 | var $input = $(this);
10 | var min = this.sliderCfg.min;
11 | var max = this.sliderCfg.max;
12 | var step = this.sliderCfg.step;
13 | var callback = this.sliderCfg.callback;
14 |
15 | $input.attr('min', min)
16 | .attr('max', max)
17 | .attr('step', step);
18 |
19 | $input.bind("input", function (e) {
20 | $input.attr('value', this.value);
21 | $input.css('background', 'linear-gradient(to right, #059CFA, white ' + (this.value - 200) / 8 + '%, white)');
22 | //其中要将this.value进行从[200,1000]到[0,100]的函数映射
23 |
24 | if ($.isFunction(callback)) {
25 | callback(this);
26 | }
27 | });
28 | };
--------------------------------------------------------------------------------
/内存管理_动态分区分配方式/src/static/js/clear.js:
--------------------------------------------------------------------------------
1 | function clearbtnClick(){
2 | console.log('clear...')
3 | var Mem = document.getElementById('memory');
4 | while(Mem.hasChildNodes()){
5 | Mem.removeChild(Mem.firstChild)
6 | }
7 |
8 | var Board = document.getElementById('board');
9 | while(Board.hasChildNodes()){
10 | Board.removeChild(Board.firstChild)
11 | }
12 |
13 | now = 0; //重置作业列表(从头开始作业调度)
14 | occupyMem.length = 0; //清空占用列表
15 | useableMem.length = 0; //清空可用列表
16 | $("#memory-size").removeClass("disable") //重置滑动条为可用
17 | }
--------------------------------------------------------------------------------
/内存管理_动态分区分配方式/src/static/js/nextAssingment.js:
--------------------------------------------------------------------------------
1 | /**
2 | * 作业类
3 | * @param {作业名称} name
4 | * @param {申请/释放的空间大小} data
5 | */
6 | function Proj(name, data) {
7 | this.name = name;
8 | this.data = data;
9 | this.getname = function () {
10 | return this.name
11 | }
12 | this.getdata = function () {
13 | return this.data
14 | }
15 | }
16 |
17 | /**
18 | * 标记类
19 | * @param {起始地址} start
20 | * @param {长度} last
21 | */
22 | function Mark(start, last) {
23 | this.start = start;
24 | this.last = last;
25 | this.getstart = function () {
26 | return this.start;
27 | }
28 | this.getlast = function () {
29 | return this.last;
30 | }
31 | }
32 |
33 | /**
34 | * 作业列表(后期可考虑动态扩充)
35 | */
36 | const projList = [
37 | new Proj("作业1", 130),
38 | new Proj("作业2", 60),
39 | new Proj("作业3", 100),
40 | new Proj("作业2", -60),
41 | new Proj("作业4", 200),
42 | new Proj("作业3", -100),
43 | new Proj("作业1", -130),
44 | new Proj("作业5", 140),
45 | new Proj("作业6", 60),
46 | new Proj("作业7", 50),
47 | new Proj("作业6", -60)
48 | ]
49 |
50 | var now = 0; //当前执行到的指令位置
51 |
52 | occupyMem = [] //被占用标记表
53 | useableMem = [] //空闲空间标记表
54 |
55 | const ADDSUCCESS = 0; //添加作业成功
56 | const ADDFAILED = 1; //添加作业失败
57 | const REMOVESUCCESS = 2; //释放作业成功
58 |
59 | /**Mark对象排序 => 依据start的大小 */
60 | var compareStart = function (x, y) {
61 | if (x.getstart() < y.getstart()) {
62 | return -1;
63 | } else if (x.getstart() > y.getstart()) {
64 | return 1;
65 | } else {
66 | return 0;
67 | }
68 | }
69 | /**Mark对象排序 => 依据last的大小 */
70 | var compareLast = function (x, y) {
71 | if (x.getlast() < y.getlast()) {
72 | return -1;
73 | } else if (x.getlast() > y.getlast()) {
74 | return 1;
75 | } else {
76 | return 0;
77 | }
78 | }
79 |
80 |
81 |
82 |
83 | /**
84 | * 内存中添加作业
85 | * 告示板中显示相应的信息
86 | */
87 | function nextAssignment() {
88 | $("#memory-size").addClass("disable") //禁用滑动条
89 |
90 | var algorithm = $("#box").attr("data-value"); //获取所选的算法
91 | var memSize = document.getElementById("slider").value; //获取当前内存大小(清空之前不会变化)
92 | var Mem = document.getElementById('memory'); //获取内存实体
93 | var Board = document.getElementById('board'); //获取告示板实体
94 |
95 | if (occupyMem == false) { //内存没有任何作业
96 | useableMem.push(new Mark(0, memSize));
97 | }
98 |
99 | if (now < projList.length) {
100 | if(Adapt(memSize,Mem,Board,algorithm)){//可以装入作业
101 | now++;
102 | }else{
103 | ;
104 | }
105 | } else {
106 | var mess = document.createElement("mess");
107 | mess.type = "div";
108 | mess.innerText = "作业已全部完成!\n";
109 | mess.style.color = "red";
110 | Board.appendChild(mess);
111 | }
112 |
113 |
114 |
115 | //滚动条自动滚到最底部
116 | Board.scrollTop = Board.scrollHeight;
117 | }
118 |
119 |
120 | /**适配算法 */
121 | function Adapt(memSize, Mem, Board, algorithm) {
122 | var name = projList[now].getname();
123 | var data = projList[now].getdata();
124 |
125 | if (data > 0) { //申请空间
126 | if(algorithm == "首次适应算法"){
127 | useableMem.sort(compareStart)
128 | }else if(algorithm == "最佳适应算法"){
129 | useableMem.sort(compareLast);
130 | }
131 | console.log("after algorithm filter...", useableMem)
132 |
133 | for (var i = 0; i < useableMem.length; ++i) {
134 | if (useableMem[i].getlast() > data) { //第一个能放下的位置
135 | start = useableMem[i].getstart();
136 | last = useableMem[i].getlast();
137 |
138 | occupyMem.push(new Mark(start, data));
139 | occupyMem.sort(compareStart)
140 |
141 | useableMem[i].start += data;
142 | useableMem[i].last -= data;
143 |
144 | addProj(Mem, name, start, data);
145 | addMess(Board, name, data, start, ADDSUCCESS);
146 |
147 | return true;
148 | }
149 | }
150 | } else { //释放空间
151 | var proj = document.getElementById("proj" + name[2]);
152 | document.getElementById("memory").removeChild(proj); //清除作业块
153 |
154 | /*获取起始位置 */
155 | var start = proj.style.marginLeft;
156 | start = Number(start.slice(0, -2));
157 | console.log(start)
158 |
159 | for (var i = 0; i < occupyMem.length; ++i) {
160 | if (occupyMem[i].getstart() == start) { //清除占用表项
161 | last = occupyMem[i].getlast();
162 | occupyMem.splice(i, 1);
163 | break;
164 | }
165 | }
166 |
167 | useableMem.push(new Mark(start, last)); //先在末尾添加一块新的可以使用的空间
168 | update(); //对可用内存重新整理
169 |
170 | addMess(Board, name, data, start, REMOVESUCCESS);
171 |
172 | return true;
173 | }
174 |
175 | addMess(Board, name, data, -1, ADDFAILED);
176 | return false;
177 | }
178 |
179 | /**
180 | * 添加一个作业块(不检测)
181 | * @param {内存实体} Mem
182 | * @param {作业名称} name
183 | * @param {起始位置} start
184 | * @param {作业数据信息} data
185 | */
186 | function addProj(Mem, name, start, data) {
187 | var proj = document.createElement("proj");
188 | proj.type = "div";
189 | proj.classname = "memory-proj";
190 | proj.id = "proj" + name[2];
191 | proj.innerText = "\n" + name + "\n" + data + "K" + "\n"; //作业块内部显示作业名和作业大小
192 | proj.style.marginTop = "1px";
193 | proj.style.background = randomHexColor(); //随机配色
194 | proj.style.height = "98px";
195 | proj.style.width = String(data) + "px"; //作业块的宽度为作业大小
196 |
197 | /*实现以内存左端点为基准定位 */
198 | proj.style.position = "absolute";
199 | proj.style.marginLeft = String(start) + "px";
200 |
201 | Mem.appendChild(proj);
202 | }
203 |
204 | /**
205 | * 添加一行日志信息
206 | * @param {告示板实体} Board
207 | * @param {作业名称} name
208 | * @param {作业数据信息} data
209 | * @param {存放的起始位置} start
210 | */
211 | function addMess(Board, name, data, start, flag) {
212 | var mess = document.createElement("mess");
213 | mess.type = "div";
214 | if (flag == ADDSUCCESS) {
215 | mess.innerText = name + "申请" + String(data) + "K内存空间成功\n" + "起始位置是" + String(start) + "\n\n";
216 | mess.style.color = "black";
217 | } else if (flag == ADDFAILED) {
218 | mess.innerText = name + "要申请" + String(data) + "K内存空间\n当前内存空间不足!\n\n";
219 | mess.style.color = "red";
220 | } else if (flag == REMOVESUCCESS) {
221 | mess.innerText = name + "释放" + String(-data) + "K内存空间成功\n\n";
222 | mess.style.color = "blue";
223 | }
224 | Board.appendChild(mess);
225 | }
226 |
227 | /**重新整理useableMem */
228 | function update() {
229 | useableMem.sort(compareStart)
230 | console.log("before update", useableMem)
231 |
232 | var i = 0;
233 | while (i < useableMem.length) {
234 | while (i + 1 < useableMem.length && //当前空闲块和后面的空闲块可以合并,持续循环合并
235 | (useableMem[i].getstart() + useableMem[i].getlast() == useableMem[i + 1].getstart())) {
236 | useableMem[i].last += useableMem[i + 1].getlast();
237 | useableMem.splice(i + 1, 1); //合并后删除后面的空闲块
238 | }
239 | ++i;
240 | }
241 | console.log("after update", useableMem)
242 | }
--------------------------------------------------------------------------------
/内存管理_动态分区分配方式/src/static/js/randColor.js:
--------------------------------------------------------------------------------
1 | function randomHexColor() { //随机生成十六进制颜色
2 | var hex = Math.floor(Math.random() * 16777216).toString(16); //生成ffffff以内16进制数
3 | while (hex.length < 6) { //while循环判断hex位数,少于6位前面加0凑够6位
4 | hex = '0' + hex;
5 | }
6 | return '#' + hex; //返回‘#'开头16进制颜色
7 | }
--------------------------------------------------------------------------------
/内存管理_动态分区分配方式/src/static/js/select.js:
--------------------------------------------------------------------------------
1 | $(function () {
2 | selectModel();
3 | });
4 |
5 | /*下拉列表选择*/
6 | function selectModel() {
7 | var $box = $('div.model-box');
8 | var $option = $('ul.model-select-option', $box);
9 | var $txt = $('div.model-select-text', $box);
10 | var speed = 10;
11 | /**
12 | * 单击某个下拉列表时,显示当前下拉列表的下拉列表框
13 | * 并隐藏页面中其他下拉列表
14 | */
15 | $txt.on('click', function () {
16 | var $self = $(this);
17 | $option.not($self).siblings('ul.model-select-option').slideUp(speed, function () {
18 | init($self);
19 | });
20 | $self.siblings('ul.model-select-option').slideToggle(speed, function () {
21 | init($self);
22 | });
23 | return false;
24 | });
25 |
26 | // 点击选择,关闭其他下拉框
27 | /**
28 | * 为每个下拉列表框中的选项设置默认选中标识 data-selected
29 | * 点击下拉列表框中的选项时,将选项的 data-option 属性的属性值赋给下拉列表的 data-value 属性,并改变默认选中标识 data-selected
30 | * 为选项添加 mouseover 事件
31 | */
32 | $option.find('li').each(function (index, element) {
33 | var $self = $(this);
34 | if ($self.hasClass('selected')) {
35 | $self.addClass('data-selected');
36 | }
37 | }).mousedown(function () {
38 | $(this).parent().siblings('div.model-select-text').text($(this).text()).attr('data-value', $(this).attr('data-option'));
39 |
40 | $option.slideUp(speed, function () {
41 | init($(this));
42 | });
43 | $(this).addClass('selected data-selected').siblings('li').removeClass('selected data-selected');
44 |
45 | //输出选择的算法
46 | console.log($("#box").attr("data-value"))
47 |
48 | return false;
49 | }).mouseover(function () {
50 | $(this).addClass('selected').siblings('li').removeClass('selected');
51 | });
52 |
53 | // 点击文档隐藏所有下拉框
54 | $(document).on('click', function () {
55 | var $self = $(this);
56 | $option.slideUp(speed, function () {
57 | init($self);
58 | })
59 | });
60 |
61 | /**
62 | * 初始化默认选择
63 | */
64 | function init(obj) {
65 | obj.find('li.data-selected').addClass('selected').siblings('li').removeClass('selected');
66 | }
67 | }
--------------------------------------------------------------------------------
/内存管理_动态分区分配方式/动态分区分配方式模拟_设计方案报告.md:
--------------------------------------------------------------------------------
1 | # 内存管理 - 动态分区分配方式模拟
2 |
3 | ###### 操作系统第二次课程作业 - 动态分区分配方式模拟
4 |
5 | ## 目录
6 |
7 | - [项目需求](#项目需求)
8 | - [项目目的](#项目目的)
9 | - [开发环境](#开发环境)
10 | - [项目结构](#项目结构)
11 | - [操作说明](#操作说明)
12 | - [系统分析](#系统分析)
13 | - [首次适应算法](#首次适应算法)
14 | - [最佳适应算法](#最佳适应算法)
15 | - [系统设计](#系统设计)
16 | - [界面设计](#界面设计)
17 | - [类设计](#类设计)
18 | - [实体设计](#实体设计)
19 | - [状态设计](#状态设计)
20 | - [系统实现](#系统实现)
21 | - [下拉框选择算法](#下拉框选择算法)
22 | - [滑动条动态调节内存大小](#滑动条动态调节内存大小)
23 | - [下一步进行作业调度](#下一步进行作业调度)
24 | - [分区分配算法](#分区分配算法)
25 | - [更新空闲空间标记表](#更新空闲空间标记表)
26 | - [添加一个作业块](#添加一个作业块)
27 | - [添加一行日志信息](#添加一行日志信息)
28 | - [清空内存](#清空内存)
29 | - [添加的作业随机颜色标识](#添加的作业随机颜色标识)
30 | - [项目功能截屏展示](#项目功能截屏展示)
31 | - [首次适应算法](#首次适应算法)
32 | - [最佳适应算法](#最佳适应算法)
33 | - [内存空间不足](#内存空间不足)
34 | - [选择动态分区分配算法](#选择动态分区分配算法)
35 | - [调节滑动条动态改变内存大小](#调节滑动条动态改变内存大小)
36 | - [点击下一步进行作业调度](#点击下一步进行作业调度)
37 | - [日志信息](#日志信息)
38 | - [作者](#作者)
39 |
40 |
41 |
42 | ## 项目需求
43 |
44 | 假设初始态下,可用内存空间为640K,并有下列请求序列,请分别用首次适应算法和最佳适应算法进行内存块的分配和回收,并显示出每次分配和回收后的空闲分区链的情况来。
45 |
46 | | 作业1申请130K |
47 | | :-----------: |
48 | | 作业2申请 60K |
49 | | 作业3申请100k |
50 | | 作业2释放 60K |
51 | | 作业4申请200K |
52 | | 作业3释放100K |
53 | | 作业1释放130K |
54 | | 作业5申请140K |
55 | | 作业6申请 60K |
56 | | 作业7申请 50K |
57 | | 作业6释放 60K |
58 |
59 |
60 |
61 |
62 |
63 | ### 项目目的
64 |
65 | - 数据结构、分配算法
66 | - 加深对动态分区存储管理方式及其实现过程的理解
67 |
68 |
69 |
70 |
71 |
72 | ## 开发环境
73 |
74 | - **开发环境:** Windows 10
75 |
76 | - **开发软件:**
77 |
78 | 1. **Visual Studio Code** *1.34.0*
79 | 2. **WebStorm** *2019.1.1.WS-191.6707.60*
80 |
81 | - **开发语言:** html, javascript, css, jQuery
82 |
83 | - **主要引用块内容:**
84 |
85 | ```html
86 |
87 | ```
88 |
89 |
90 |
91 |
92 |
93 | ## 项目结构
94 | ```
95 | │ README.md
96 | │ 动态分区分配方式模拟_设计方案报告.md
97 | │ 动态分区分配方式模拟_设计方案报告.pdf
98 | │
99 | ├─Resource
100 | │ memory.png
101 | │
102 | └─src
103 | │ Dynamic partition allocation.html
104 | │
105 | └─static
106 | ├─css
107 | │ range.css
108 | │ style.css
109 | │
110 | └─js
111 | clear.js
112 | nextAssingment.js
113 | randColor.js
114 | RangeSlider.js
115 | select.js
116 | ```
117 |
118 |
119 |
120 |
121 | ## 操作说明
122 |
123 | - 双击目录`src`下的`Dynamic partition allocation.html`文件, 并在浏览器中打开,打开后界面如下图所示
124 |
125 | 
126 |
127 | - 选择希望进行模拟的动态分区分配算法*(首次适应算法/最佳适应算法)*
128 |
129 | 
130 |
131 | - 调节滑动条改变当前内存大小*(上方模拟链式空间长度会随着滑动条滑动而动态变化)*
132 |
133 | 
134 |
135 | - 点击**下一步**进行作业调度
136 |
137 | 
138 |
139 | - 上方的模拟内存会显示每次分配和回收后的空闲分区链的情况*(不同作业的颜色不同, 以区分不同作业在内存中的位置分布情况)*
140 |
141 | 
142 |
143 | - 下方的日志信息会显示作业*申请/释放*等信息
144 |
145 | 
146 |
147 | - 点击**清空内存**会清空内存中的作业以及日志信息全部内容, 此时可再次调整内存空间大小, 并再次进行动态分区分配方式模拟
148 |
149 |
150 |
151 |
152 |
153 | ## 系统分析
154 |
155 |
156 |
157 | - ### **首次适应算法**
158 |
159 | - 算法逻辑: 记录当前内存中被使用的空间, 同时记录当前内存中可以使用的空间(并将其按照物理位置顺序列出)
160 |
161 | 如果当前作业需要申请内存空间 => 顺序查找第一个空闲块大小大于所需空间 => 将占用的内存空标记为被使用 => 空闲块大小和位置做相应的调整
162 |
163 |
164 |
165 | - ### **最佳适应算法**
166 |
167 | - 算法逻辑: 同样记录当前内存中被使用的空间, 同时记录当前内存中可以使用的空间(并将其按照物理容量大小列出)
168 |
169 | 如果当前作业需要申请内存空间 => 找出当前容量最小并且满足当前申请需求的物理块 => 将占用的内存空标记为被使用 => 空闲块大小和位置做相应的调整
170 |
171 |
172 |
173 |
174 |
175 | ## 系统设计
176 |
177 |
178 |
179 | ### 界面设计
180 |
181 | 1. **整体设计**
182 |
183 | 
184 |
185 | 2. **内存模型**:
186 |
187 | ```html
188 |
189 |
190 |
191 |
192 |
193 |
194 |
195 |
196 | ```
197 |
198 | ```css
199 | /*中部链式内存样式*/
200 | .memory {
201 | margin-top: 5%;
202 | height: 100px;
203 | width: 200px;
204 | border-top: 4px solid black;
205 | border-bottom: 4px solid black;
206 | display: flex;
207 | position: relative;
208 | }
209 | ```
210 |
211 | 3. **作业块:**
212 |
213 | ```css
214 | /*内存中的每一个作业*/
215 | .memory-proj {
216 | margin-top: 1px;
217 | background-color: rgb(111, 120, 172);
218 | height: 98px;
219 | width: 100px;
220 | position: absolute;
221 | }
222 | ```
223 |
224 |
225 | 4. **选择算法(下拉框)**:
226 |
227 | ```html
228 |
229 |
230 |
请选择分区分配算法
231 |
232 |
首次适应算法
233 |
234 |
235 | - 首次适应算法
236 | - 最佳适应算法
237 |
238 |
239 |
240 | ```
241 |
242 | ```css
243 | /*下拉框*/
244 | .model-box {
245 | position: relative;
246 | width: 200px;
247 | height: 30px;
248 | line-height: 30px;
249 | background-color: #fff;
250 | border: 1px solid #e4e4e4;
251 | border-radius: 3px;
252 | text-indent: 5px;
253 | }
254 |
255 | /*下拉框中待选文字*/
256 | .model-box .model-select-text {
257 | position: relative;
258 | width: 100%;
259 | height: 28px;
260 | color: #666;
261 | text-indent: 10px;
262 | font-size: 14px;
263 | cursor: pointer;
264 | user-select: none;
265 | }
266 |
267 | .model-box .model-select-text:after {
268 | position: absolute;
269 | top: 10px;
270 | right: 10px;
271 | content: '';
272 | width: 0;
273 | height: 0;
274 | border-width: 10px 8px 0;
275 | border-style: solid;
276 | border-color: #666 transparent transparent;
277 | }
278 |
279 | .model-box .model-select-option {
280 | position: absolute;
281 | top: 30px;
282 | left: -1px;
283 | display: none;
284 | list-style: none;
285 | border: 1px solid #e4e4e4;
286 | border-top: none;
287 | padding: 0;
288 | margin: 0;
289 | width: 100%;
290 | z-index: 99;
291 | background-color: #fff;
292 | }
293 |
294 | .model-box .model-select-option li {
295 | height: 28px;
296 | line-height: 28px;
297 | color: #333;
298 | font-size: 14px;
299 | margin: 0;
300 | padding: 0;
301 | cursor: pointer;
302 | }
303 |
304 | .model-box .model-select-option li:hover {
305 | background-color: #f3f3f3;
306 | }
307 |
308 | .model-box .model-select-option li.seleced {
309 | background-color: #f3f3f3;
310 | }
311 | ```
312 |
313 |
314 |
315 | 5. **选择内存大小(滑动条)**:
316 |
317 | ```html
318 |
319 |
320 |
请选择内存空间大小
321 |
200
322 | K
323 |
324 |
325 |
326 |
327 |
328 | ```
329 |
330 | ```css
331 | /*去除系统默认的样式*/
332 | input[type=range] {
333 | -webkit-appearance: none;
334 | width: 300px;
335 | border-radius: 10px;
336 | /*这个属性设置使填充进度条时的图形为圆角*/
337 | }
338 |
339 | input[type=range]::-webkit-slider-thumb {
340 | -webkit-appearance: none;
341 | }
342 |
343 | /*自定义滑动控件的轨道*/
344 | input[type=range]::-webkit-slider-runnable-track {
345 | height: 15px;
346 | border-radius: 10px;
347 | /*将轨道设为圆角的*/
348 | box-shadow: 0 1px 1px #def3f8, inset 0 .125em .125em #0d1112;
349 | /*轨道内置阴影效果*/
350 | }
351 | /*原始的控件获取到焦点时,会显示包裹整个控件的边框,所以还需要把边框取消。*/
352 | input[type=range]:focus {
353 | outline: none;
354 | }
355 |
356 | input[type=range]::-webkit-slider-thumb {
357 | -webkit-appearance: none;
358 | height: 25px;
359 | width: 25px;
360 | margin-top: -5px; /*使滑块超出轨道部分的偏移量相等*/
361 | background: #ffffff;
362 | border-radius: 50%; /*外观设置为圆形*/
363 | border: solid 0.125em rgba(205, 224, 230, 0.5); /*设置边框*/
364 | box-shadow: 0 .125em .125em #3b4547; /*添加底部阴影*/
365 | }
366 | ```
367 |
368 | 6. **下一步/清空内存(按钮)**:
369 |
370 | ```html
371 |
372 |
373 |
377 |
378 |
379 |
380 |
381 |
385 |
386 | ```
387 |
388 | 7. **日志信息(滚动div)**:
389 |
390 | ```html
391 |
392 |
393 |
394 | 日志信息
395 |
397 |
398 |
399 |
400 | ```
401 |
402 |
403 |
404 |
405 | ### 类设计
406 |
407 | 1. **作业类:** 作业实体
408 |
409 | ```javascript
410 | /**
411 | * 作业类
412 | * @param {作业名称} name
413 | * @param {申请/释放的空间大小} data
414 | */
415 | function Proj(name, data) {
416 | this.name = name;
417 | this.data = data;
418 | this.getname = function () {
419 | return this.name
420 | }
421 | this.getdata = function () {
422 | return this.data
423 | }
424 | }
425 | ```
426 |
427 | 2. **标记类:** 标记作业在内存中的起始地址和长度
428 |
429 | ```javascript
430 | /**
431 | * 标记类
432 | * @param {起始地址} start
433 | * @param {长度} last
434 | */
435 | function Mark(start, last) {
436 | this.start = start;
437 | this.last = last;
438 | this.getstart = function () {
439 | return this.start;
440 | }
441 | this.getlast = function () {
442 | return this.last;
443 | }
444 | }
445 | ```
446 |
447 |
448 |
449 |
450 | ### 实体设计
451 |
452 | 1. **作业列表:**
453 |
454 | ```javascript
455 | /**
456 | * 作业列表(后期可考虑动态扩充)
457 | */
458 | const projList = [
459 | new Proj("作业1", 130),
460 | new Proj("作业2", 60),
461 | new Proj("作业3", 100),
462 | new Proj("作业2", -60),
463 | new Proj("作业4", 200),
464 | new Proj("作业3", -100),
465 | new Proj("作业1", -130),
466 | new Proj("作业5", 140),
467 | new Proj("作业6", 60),
468 | new Proj("作业7", 50),
469 | new Proj("作业6", -60)
470 | ]
471 | ```
472 |
473 | 2. **被占用标记表:** `occupyMem = []`
474 |
475 | 3. **空闲空间标记表:** `useableMem = []`
476 |
477 |
478 |
479 | ### 状态设计
480 |
481 | 1. 添加作业成功: `const ADDSUCCESS = 0; `
482 | 2. 添加作业失败: `const ADDFAILED = 1; `
483 | 3. 释放作业成功: `const REMOVESUCCESS = 2;`
484 |
485 |
486 |
487 |
488 |
489 | ## 系统实现
490 |
491 |
492 |
493 | ### 下拉框选择算法
494 |
495 | - 单击某个下拉列表, 显示当前下拉列表的下拉列表框, 并隐藏页面中其他下拉列表
496 |
497 | - 点击选择,关闭其他下拉框
498 |
499 | - 点击文档隐藏所有下拉框
500 |
501 | ```javascript
502 | $(function () {
503 | selectModel();
504 | });
505 |
506 | /*下拉列表选择*/
507 | function selectModel() {
508 | var $box = $('div.model-box');
509 | var $option = $('ul.model-select-option', $box);
510 | var $txt = $('div.model-select-text', $box);
511 | var speed = 10;
512 | /**
513 | * 单击某个下拉列表时,显示当前下拉列表的下拉列表框
514 | * 并隐藏页面中其他下拉列表
515 | */
516 | $txt.on('click', function () {
517 | var $self = $(this);
518 | $option.not($self).siblings('ul.model-select-option').slideUp(speed, function () {
519 | init($self);
520 | });
521 | $self.siblings('ul.model-select-option').slideToggle(speed, function () {
522 | init($self);
523 | });
524 | return false;
525 | });
526 |
527 | // 点击选择,关闭其他下拉框
528 | /**
529 | * 为每个下拉列表框中的选项设置默认选中标识 data-selected
530 | * 点击下拉列表框中的选项时,将选项的 data-option 属性的属性值赋给下拉列表的 data-value 属性,并改变默认选中标识 data-selected
531 | * 为选项添加 mouseover 事件
532 | */
533 | $option.find('li').each(function (index, element) {
534 | var $self = $(this);
535 | if ($self.hasClass('selected')) {
536 | $self.addClass('data-selected');
537 | }
538 | }).mousedown(function () {
539 | $(this).parent().siblings('div.model-select-text').text($(this).text()).attr('data-value', $(this).attr('data-option'));
540 |
541 | $option.slideUp(speed, function () {
542 | init($(this));
543 | });
544 | $(this).addClass('selected data-selected').siblings('li').removeClass('selected data-selected');
545 |
546 | //输出选择的算法
547 | console.log($("#box").attr("data-value"))
548 |
549 | return false;
550 | }).mouseover(function () {
551 | $(this).addClass('selected').siblings('li').removeClass('selected');
552 | });
553 |
554 | // 点击文档隐藏所有下拉框
555 | $(document).on('click', function () {
556 | var $self = $(this);
557 | $option.slideUp(speed, function () {
558 | init($self);
559 | })
560 | });
561 |
562 | /**
563 | * 初始化默认选择
564 | */
565 | function init(obj) {
566 | obj.find('li.data-selected').addClass('selected').siblings('li').removeClass('selected');
567 | }
568 | }
569 | ```
570 |
571 |
572 |
573 |
574 | ### 滑动条动态调节内存大小
575 |
576 | - 内存设置为200K~1000K可动态改变
577 |
578 | - 初始化滚动条处于最左端(内存容量为最小值), 最小移动步长为20K
579 |
580 | - 使用html5提供的``创建滚动条并绑定`change()`事件
581 |
582 | ```javascript
583 | //滑动条改变触发事件
584 | var change = function ($input) {
585 | console.log($input.value)
586 | //将slider的值进行函数映射
587 | document.getElementById('current-size').innerHTML = $input.value;
588 | document.getElementById('memory').style.width = String($input.value) + "px";
589 | }
590 |
591 | $('input').RangeSlider({
592 | min: 200,
593 | max: 1000,
594 | step: 20,
595 | callback: change
596 | });
597 | ```
598 |
599 | - 根据滑动条当前`value`进行函数映射, 对应到内存的当前大小, 并填充色块代表选择的范围
600 |
601 | ```javascript
602 | $.fn.RangeSlider = function (cfg) {
603 | this.sliderCfg = {
604 | min: cfg && !isNaN(parseFloat(cfg.min)) ? Number(cfg.min) : null,
605 | max: cfg && !isNaN(parseFloat(cfg.max)) ? Number(cfg.max) : null,
606 | step: cfg && Number(cfg.step) ? cfg.step : 1,
607 | callback: cfg && cfg.callback ? cfg.callback : null
608 | };
609 |
610 | var $input = $(this);
611 | var min = this.sliderCfg.min;
612 | var max = this.sliderCfg.max;
613 | var step = this.sliderCfg.step;
614 | var callback = this.sliderCfg.callback;
615 |
616 | $input.attr('min', min)
617 | .attr('max', max)
618 | .attr('step', step);
619 |
620 | $input.bind("input", function (e) {
621 | $input.attr('value', this.value);
622 | $input.css('background', 'linear-gradient(to right, #059CFA, white ' + (this.value - 200) / 8 + '%, white)');
623 | //其中要将this.value进行从[200,1000]到[0,100]的函数映射
624 |
625 | if ($.isFunction(callback)) {
626 | callback(this);
627 | }
628 | });
629 | };
630 | ```
631 |
632 | - 将用户选择的当前内存容量显示到滑动条的上方便于用户账务内存容量信息
633 |
634 | - 用户点击下一步后滑动条失效(不可以再更改内存空间大小)
635 |
636 | - 用户点击清空内存后滑动条恢复
637 |
638 |
639 |
640 | ### 下一步进行作业调度
641 |
642 | - 设定**全局定位器**`now = 0`用于标识当前执行任务列表的第几条
643 |
644 | - 设定**被占用标记表**`occupyMem`和**空闲空间标记表**`useableMem`
645 |
646 | - 依据now值进行分支处理:
647 |
648 | - 如果now值为0 => 内存中没有任何作业 => 全部内存空间标记为可使用 => 起始位置为0, 长度为当前内存空间大小
649 |
650 | ```javascript
651 | if (occupyMem == false) { //内存没有任何作业
652 | useableMem.push(new Mark(0, memSize));
653 | }
654 | ```
655 |
656 | - 如果now值小于任务列表的长度 => 继续执行下一条指令
657 |
658 | - 如果now值大于等于任务列表的长度 => 所有任务已经执行完毕 => 输出相应日志信息
659 |
660 | ```javascript
661 | var mess = document.createElement("mess");
662 | mess.type = "div";
663 | mess.innerText = "作业已全部完成!\n";
664 | mess.style.color = "red";
665 | Board.appendChild(mess);
666 | ```
667 |
668 | - 执行下一条指令时:
669 |
670 | - 如果可以装入作业 => now指向下一条待执行的指令
671 |
672 |
673 |
674 | ### 分区分配算法
675 |
676 | - 如果该指令是要申请空间:
677 |
678 | - 首次适应算法:
679 |
680 | - 依照`Mark`的起始位置将空闲空间表进行排序
681 | - 寻找第一个能放下该作业的位置
682 |
683 | - 最佳适应算法:
684 |
685 | - 依照`Mark`的大小将空闲空间表进行排序
686 | - 寻找能放下该作业的最小内存位置
687 |
688 | ```javascript
689 | if(algorithm == "首次适应算法"){
690 | useableMem.sort(compareStart)
691 | }else if(algorithm == "最佳适应算法"){
692 | useableMem.sort(compareLast);
693 | }
694 | ```
695 |
696 | - 将这段空间记录在被占用标记表中 => 将被占用标记表重新排序
697 |
698 | - 将该段的空闲空间表起始位置加上作业申请的内存空间大小
699 |
700 | - 将该段的空闲空间表大小减去作业申请的内存空间大小
701 |
702 | - 在模拟的内存中添加一个作业块
703 |
704 | - 在日志信息中增加一行申请成功的日志
705 |
706 | ```javascript
707 | for (var i = 0; i < useableMem.length; ++i) {
708 | if (useableMem[i].getlast() > data) { //第一个能放下的位置
709 | start = useableMem[i].getstart();
710 | last = useableMem[i].getlast();
711 |
712 | occupyMem.push(new Mark(start, data));
713 | occupyMem.sort(compareStart)
714 |
715 | useableMem[i].start += data;
716 | useableMem[i].last -= data;
717 |
718 | addProj(Mem, name, start, data);
719 | addMess(Board, name, data, start, ADDSUCCESS);
720 |
721 | return true;
722 | }
723 | }
724 | ```
725 |
726 | - 如果该指令是要释放空间:
727 |
728 | - 在模拟内存中清除该作业块
729 |
730 | - 获取该作业的起始位置
731 |
732 | - 清除占用表中该作业的项
733 |
734 | - 在空闲空间表末尾添加一块新的可以使用的空间
735 |
736 | - 对可用内存重新整理
737 |
738 | - 添加一条释放成功的日志信息
739 |
740 | ```javascript
741 | var proj = document.getElementById("proj" + name[2]);
742 | document.getElementById("memory").removeChild(proj); //清除作业块
743 |
744 | /*获取起始位置 */
745 | var start = proj.style.marginLeft;
746 | start = Number(start.slice(0, -2));
747 | console.log(start)
748 |
749 | for (var i = 0; i < occupyMem.length; ++i) {
750 | if (occupyMem[i].getstart() == start) { //清除占用表项
751 | last = occupyMem[i].getlast();
752 | occupyMem.splice(i, 1);
753 | break;
754 | }
755 | }
756 |
757 | useableMem.push(new Mark(start, last)); //先在末尾添加一块新的可以使用的空间
758 | update(); //对可用内存重新整理
759 |
760 | addMess(Board, name, data, start, REMOVESUCCESS);
761 |
762 | return true;
763 | ```
764 |
765 | - 如果申请失败:
766 |
767 | - 在日志信息中添加一条申请失败的日志信息
768 |
769 | ```javascript
770 | addMess(Board, name, data, -1, ADDFAILED);
771 | return false;
772 | ```
773 |
774 |
775 |
776 | ### 更新空闲空间标记表
777 |
778 | - 每次释放一个作业之后要对空闲空间表进行更新
779 |
780 | - 先将其依照`Mark`的起始位置进行排序
781 |
782 | - 当前空闲块和后面的空闲块可以合并, 持续循环合并 => 合并后删除后面的空闲块
783 |
784 | - 直到标记表被整个遍历完
785 |
786 | ```javascript
787 | /**重新整理useableMem */
788 | function update() {
789 | useableMem.sort(compareStart)
790 | console.log("before update", useableMem)
791 |
792 | var i = 0;
793 | while (i < useableMem.length) {
794 | while (i + 1 < useableMem.length && //当前空闲块和后面的空闲块可以合并,持续循环合并
795 | (useableMem[i].getstart() + useableMem[i].getlast() == useableMem[i + 1].getstart())) {
796 | useableMem[i].last += useableMem[i + 1].getlast();
797 | useableMem.splice(i + 1, 1); //合并后删除后面的空闲块
798 | }
799 | ++i;
800 | }
801 | console.log("after update", useableMem)
802 | }
803 | ```
804 |
805 |
806 |
807 |
808 | ### 添加一个作业块
809 |
810 | ```javascript
811 | /**
812 | * 添加一个作业块(不检测)
813 | * @param {内存实体} Mem
814 | * @param {作业名称} name
815 | * @param {起始位置} start
816 | * @param {作业数据信息} data
817 | */
818 | function addProj(Mem, name, start, data) {
819 | var proj = document.createElement("proj");
820 | proj.type = "div";
821 | proj.classname = "memory-proj";
822 | proj.id = "proj" + name[2];
823 | proj.innerText = "\n" + name + "\n" + data + "K" + "\n"; //作业块内部显示作业名和作业大小
824 | proj.style.marginTop = "1px";
825 | proj.style.background = randomHexColor(); //随机配色
826 | proj.style.height = "98px";
827 | proj.style.width = String(data) + "px"; //作业块的宽度为作业大小
828 |
829 | /*实现以内存左端点为基准定位 */
830 | proj.style.position = "absolute";
831 | proj.style.marginLeft = String(start) + "px";
832 |
833 | Mem.appendChild(proj);
834 | }
835 |
836 | ```
837 |
838 |
839 |
840 | ### 添加一行日志信息
841 |
842 | - 作业申请内存成功: 输出作业编号, 释放内存大小, 内存中的起始位置
843 | - 作业申请内存失败: 输出作业编号, 释放内存大小, 当前内存空间不足
844 | - 作业释放内存成功: 输出作业编号, 释放内存大小
845 |
846 | ```javascript
847 | /**
848 | * 添加一行日志信息
849 | * @param {告示板实体} Board
850 | * @param {作业名称} name
851 | * @param {作业数据信息} data
852 | * @param {存放的起始位置} start
853 | */
854 | function addMess(Board, name, data, start, flag) {
855 | var mess = document.createElement("mess");
856 | mess.type = "div";
857 | if (flag == ADDSUCCESS) {
858 | mess.innerText = name + "申请" + String(data) + "K内存空间成功\n" + "起始位置是" + String(start) + "\n\n";
859 | mess.style.color = "black";
860 | } else if (flag == ADDFAILED) {
861 | mess.innerText = name + "要申请" + String(data) + "K内存空间\n当前内存空间不足!\n\n";
862 | mess.style.color = "red";
863 | } else if (flag == REMOVESUCCESS) {
864 | mess.innerText = name + "释放" + String(-data) + "K内存空间成功\n\n";
865 | mess.style.color = "blue";
866 | }
867 | Board.appendChild(mess);
868 | }
869 | ```
870 |
871 |
872 |
873 | ### 清空内存
874 |
875 | - 用户点击`清空内存`按钮 => 清除模拟内存中的所有作业块 => 清空日志信息中的所有日志 => 重置作业列表(从头开始作业调度) => 清空占用列表 => 清空可用列表 => 重置滑动条为可用
876 |
877 | ```javascript
878 | function clearbtnClick(){
879 | console.log('clear...')
880 | var Mem = document.getElementById('memory');
881 | while(Mem.hasChildNodes()){
882 | Mem.removeChild(Mem.firstChild)
883 | }
884 |
885 | var Board = document.getElementById('board');
886 | while(Board.hasChildNodes()){
887 | Board.removeChild(Board.firstChild)
888 | }
889 |
890 | now = 0; //重置作业列表(从头开始作业调度)
891 | occupyMem.length = 0; //清空占用列表
892 | useableMem.length = 0; //清空可用列表
893 | $("#memory-size").removeClass("disable") //重置滑动条为可用
894 | }
895 | ```
896 |
897 |
898 |
899 | ### 添加的作业随机颜色标识
900 |
901 | - 添加到模拟内存中的作业会被随机配色以示区分
902 |
903 | ```javascript
904 | function randomHexColor() { //随机生成十六进制颜色
905 | var hex = Math.floor(Math.random() * 16777216).toString(16); //生成ffffff以内16进制数
906 | while (hex.length < 6) { //while循环判断hex位数,少于6位前面加0凑够6位
907 | hex = '0' + hex;
908 | }
909 | return '#' + hex; //返回‘#'开头16进制颜色
910 | }
911 | ```
912 |
913 |
914 |
915 |
916 |
917 | ## 功能实现截屏展示
918 |
919 |
920 |
921 | ### 首次适应算法
922 |
923 | 
924 |
925 |
926 |
927 | ### 最佳适应算法
928 |
929 | 
930 |
931 |
932 |
933 | ### 内存空间不足
934 |
935 | 
936 |
937 |
938 |
939 | ### 选择动态分区分配算法
940 |
941 | 
942 |
943 |
944 |
945 | ### 调节滑动条动态改变内存大小
946 |
947 | 
948 |
949 |
950 |
951 | ### 点击下一步进行作业调度
952 |
953 | 
954 |
955 |
956 |
957 | ### 日志信息
958 |
959 | 
960 |
961 |
962 |
963 |
964 |
965 | #### 作者
966 |
967 | **学号** 1754060
968 |
969 | **姓名** 张喆
970 |
971 | **指导老师** 王冬青老师
972 |
973 | **上课时间** 周三/周五 上午一二节
974 |
975 | **联系方式** *email:* doubleZ0108@gmail.com
976 |
977 |
--------------------------------------------------------------------------------
/内存管理_动态分区分配方式/动态分区分配方式模拟_设计方案报告.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/doubleZ0108/Operating-System/f00305ef02f4c4b7a92252947dcd559e7602c434/内存管理_动态分区分配方式/动态分区分配方式模拟_设计方案报告.pdf
--------------------------------------------------------------------------------
/内存管理_请求分区分配方式/DemandPaging.exe:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/doubleZ0108/Operating-System/f00305ef02f4c4b7a92252947dcd559e7602c434/内存管理_请求分区分配方式/DemandPaging.exe
--------------------------------------------------------------------------------
/内存管理_请求分区分配方式/README.md:
--------------------------------------------------------------------------------
1 | # 内存管理 - 请求分区分配方式模拟
2 |
3 | ###### 操作系统第二次课程作业 - 请求分区分配方式模拟
4 |
5 | ## 目录
6 |
7 | - [开发环境](#开发环境)
8 | - [操作说明](#操作说明)
9 | - [项目结构](#项目结构)
10 | - [作者](#作者)
11 |
12 |
13 |
14 | ## 开发环境
15 |
16 | - **开发环境:** Windows 10
17 |
18 | - **开发软件:**
19 |
20 | **Visual Studio 2017** *15.9.28307.665*
21 |
22 | - **开发语言:** C++
23 |
24 |
25 |
26 |
27 | ## 操作说明
28 |
29 | - 双击目录下`DemandPaing.exe`可执行文件进入模拟界面
30 |
31 | 
32 |
33 | - 选择置换算法:
34 |
35 | - 键入`a`或`A`代表选择LRU算法
36 |
37 | - 键入`b`或`B`代表选择FIFO算法
38 |
39 | - 输入无效算法将受到提示, 并允许重新选择
40 |
41 | 
42 |
43 | - 选择执行模式:
44 |
45 | 
46 |
47 | - 键入`a`或`A`代表只执行前320条指令(指令可能重复)
48 |
49 | - 键入`b`或`B`代表执行完所有指令(知道所有指令都被执行为止)
50 |
51 | - 输入无效执行模式将受到提示, 并允许重新选择
52 |
53 | 
54 |
55 | - 查看对应算法和对应执行模式下的模拟结果
56 |
57 | 
58 |
59 | - 选择功能:
60 |
61 | 
62 |
63 | - 键入`a`或`A`代表初始化内存(可再次进行模拟)
64 | - 键入`b`或`B`代表结束程序
65 |
66 | - 初始化
67 |
68 | 
69 |
70 | - 结束程序
71 |
72 | 
73 |
74 |
75 |
76 |
77 | ## 项目结构
78 | ```
79 | │ list.txt
80 | │ README.md
81 | │ 请求分区分配方式模拟_设计方案报告.md
82 | │ 请求分区分配方式模拟_设计方案报告.pdf
83 | │
84 | └─src
85 | DemandPaging.cpp
86 | ```
87 |
88 |
89 |
90 | #### 作者
91 |
92 | **学号** 1754060
93 |
94 | **姓名** 张喆
95 |
96 | **指导老师** 王冬青老师
97 |
98 | **上课时间** 周三/周五 上午一二节
99 |
100 | **联系方式** *email:* doubleZ0108@gmail.com
101 |
--------------------------------------------------------------------------------
/内存管理_请求分区分配方式/src/DemandPaging.cpp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/doubleZ0108/Operating-System/f00305ef02f4c4b7a92252947dcd559e7602c434/内存管理_请求分区分配方式/src/DemandPaging.cpp
--------------------------------------------------------------------------------
/内存管理_请求分区分配方式/请求分区分配方式模拟_设计方案报告.md:
--------------------------------------------------------------------------------
1 | # 内存管理 - 动态分区分配方式模拟
2 |
3 | 操作系统第二次课程作业 - 动态分区分配方式模拟
4 |
5 | Table of Contents
6 | =================
7 |
8 | * [内存管理 - 动态分区分配方式模拟](#内存管理---动态分区分配方式模拟)
9 | * [项目需求](#项目需求)
10 | * [基本任务](#基本任务)
11 | * [功能描述](#功能描述)
12 | * [项目目的](#项目目的)
13 | * [开发环境](#开发环境)
14 | * [项目结构](#项目结构)
15 | * [操作说明](#操作说明)
16 | * [系统分析](#系统分析)
17 | * [置换算法](#置换算法)
18 | * [LRU算法](#lru算法)
19 | * [FIFO算法](#fifo算法)
20 | * [执行模式](#执行模式)
21 | * [320条指令产生方式](#320条指令产生方式)
22 | * [系统设计](#系统设计)
23 | * [类设计](#类设计)
24 | * [内存](#内存)
25 | * [实体设计](#实体设计)
26 | * [状态设计](#状态设计)
27 | * [系统实现](#系统实现)
28 | * [请求调页存储管理方式模拟](#请求调页存储管理方式模拟)
29 | * [执行前320条指令](#执行前320条指令)
30 | * [执行完所有指令](#执行完所有指令)
31 | * [执行一条指令](#执行一条指令)
32 | * [请求调页](#请求调页)
33 | * [打印信息](#打印信息)
34 | * [产生随机指令](#产生随机指令)
35 | * [功能实现截屏展示](#功能实现截屏展示)
36 | * [选择配置](#选择配置)
37 | * [模拟过程](#模拟过程)
38 | * [模拟结果](#模拟结果)
39 | * [实验小结](#实验小结)
40 | * [实验结果对比](#实验结果对比)
41 | * [LRU算法, 执行完所有指令](#lru算法-执行完所有指令)
42 | * [FIFO算法, 执行完所有指令](#fifo算法-执行完所有指令)
43 | * [LRU算法, 执行前320条指令](#lru算法-执行前320条指令)
44 | * [FIFO算法, 执行前320条指令](#fifo算法-执行前320条指令)
45 | * [分析](#分析)
46 | * [作者](#作者)
47 | -----
48 | ## 项目需求
49 |
50 | ### 基本任务
51 |
52 | 假设每个页面可存放10条指令,分配给一个作业的内存块为4。模拟一个作业的执行过程,该作业有320条指令,即它的地址空间为32页,目前所有页还没有调入内存。
53 |
54 | ### 功能描述
55 |
56 | - 在模拟过程中,如果所访问指令在内存中,则显示其物理地址,并转到下一条指令;如果没有在内存中,则发生缺页,此时需要记录缺页次数,并将其调入内存。如果4个内存块中已装入作业,则需进行页面置换。
57 | - 所有320条指令执行完成后,计算并显示作业执行过程中发生的缺页率。
58 |
59 | - 置换算法可以选用FIFO或者LRU算法
60 |
61 | - 作业中指令访问次序可以按照下面原则形成:
62 |
63 | 50%的指令是顺序执行的,25%是均匀分布在前地址部分,25%是均匀分布在后地址部分
64 |
65 | ### 项目目的
66 |
67 | - 页面、页表、地址转换
68 | - 页面置换过程
69 | - 加深对请求调页系统的原理和实现过程的理解。
70 |
71 |
72 |
73 | ## 开发环境
74 |
75 | - **开发环境:** Windows 10
76 |
77 | - **开发软件:**
78 |
79 | **Visual Studio 2017** *15.9.28307.665*
80 |
81 | - **开发语言:** C++
82 |
83 |
84 |
85 | ## 项目结构
86 |
87 | ```
88 | │ list.txt
89 | │ README.md
90 | │ 请求分区分配方式模拟_设计方案报告.md
91 | │ 请求分区分配方式模拟_设计方案报告.pdf
92 | │
93 | └─src
94 | DemandPaging.cpp
95 | ```
96 |
97 |
98 | ## 操作说明
99 |
100 | - 双击目录下`DemandPaing.exe`可执行文件进入模拟界面
101 |
102 | 
103 |
104 | - 选择置换算法:
105 |
106 | - 键入`a`或`A`代表选择LRU算法
107 |
108 | - 键入`b`或`B`代表选择FIFO算法
109 |
110 | - 输入无效算法将受到提示, 并允许重新选择
111 |
112 | 
113 |
114 | - 选择执行模式:
115 |
116 | 
117 |
118 | - 键入`a`或`A`代表只执行前320条指令(指令可能重复)
119 |
120 | - 键入`b`或`B`代表执行完所有指令(知道所有指令都被执行为止)
121 |
122 | - 输入无效执行模式将受到提示, 并允许重新选择
123 |
124 | 
125 |
126 | - 查看对应算法和对应执行模式下的模拟结果
127 |
128 | 
129 |
130 | - 选择功能:
131 |
132 | 
133 |
134 | - 键入`a`或`A`代表初始化内存(可再次进行模拟)
135 | - 键入`b`或`B`代表结束程序
136 |
137 | - 初始化
138 |
139 | 
140 |
141 | - 结束程序
142 |
143 | 
144 |
145 |
146 |
147 | ## 系统分析
148 |
149 | ### 置换算法
150 |
151 | #### LRU算法
152 |
153 | - **当前页面已经在内存中** => 不需要进行调度
154 | - 当**内存中页面数小于内存容量**时 => 直接将页面顺序加入到内存的空闲块中
155 | - 当**内存满**时 => 每次替换掉最近最少使用的内存块中的页面
156 | - **维护一个`LRU队列`:** 每当发生替换时取出队列头元素 => 将该内存块中的页面作为被替换掉的页面 => 将新页面加入到该页面中 => 将该内存块号重新压队
157 | - **为每个内存中的页面维护一个变量`sinceTime`:** 当需要进行页面替换的时候 => 选择`sinceTime`最大的页面替换掉 => 将新页面加入到该页面所在内存块中 => 将新页面的`sinceTime`置为0 => 内存中其他页面的`sinceTime`递增1
158 | - *本模拟程序选择的是第一种方法, 即维护LRU队列*
159 |
160 | #### FIFO算法
161 |
162 | - 当前页面已经在内存中** => 不需要进行调度
163 | - 当**内存中页面数小于内存容量**时 => 直接将页面顺序加入到内存的空闲块中
164 | - 当**内存满**时 => 每次一次替换掉内存块中的页面
165 | - 维护变量`adjustTime`, 用来计算缺页次数
166 | - `adjustTime`为1 => 将0号内存的页调出, 将当前指令调入0号内存中
167 | - `adjustTime`为2 => 将1号内存的页调出, 将当前指令调入1号内存中
168 | - `adjustTime`为3 => 将2号内存的页调出, 将当前指令调入2号内存中
169 | - `adjustTime`为4 => 将3号内存的页调出, 将当前指令调入3号内存中
170 |
171 |
172 |
173 | ### 执行模式
174 |
175 | #### 320条指令产生方式
176 |
177 | 为了保证320 条指令能够随机产生,并且能够均匀分布,采用了下面这种循环产生指令的方式:
178 |
179 | - 在0-319条指令之间,随机选取一个起始执行指令,如序号为m
180 |
181 | - 顺序执行下一条指令,即序号为m+1的指令
182 |
183 | - 通过随机数,跳转到前地址部分0-m-1中的某个指令处,其序号为m1
184 |
185 | - 顺序执行下一条指令,即序号为m1+1的指令
186 |
187 | - 通过随机数,跳转到后地址部分m1+2~319中的某条指令处,其序号为m2
188 |
189 | - 顺序执行下一条指令,即m2+1处的指令。
190 |
191 | 重复跳转到前地址部分、顺序执行、跳转到后地址部分、顺序执行的过程,直到执行完320条指令。
192 |
193 |
194 |
195 | ## 系统设计
196 |
197 | ### 类设计
198 |
199 | #### 内存
200 |
201 | ```c++
202 | class Memory
203 | {
204 | private:
205 | vector block; //内存块
206 | vector visited; //是否执行过该指令
207 | queue LRU_Queue; //最近最少使用队列
208 |
209 | int runTime = 0; //运行次数
210 | int adjustTime = 0; //调页次数
211 | int restInst = TOTALNUM; //剩余未执行指令
212 |
213 | void execute(string algorithm, InstNum aim); //按照算法执行一条指令
214 | PageNum adjust(string algorithm, BlockNum &pos); //页面置换
215 |
216 | void displayPosMess(InstNum aim) { //打印指令地址信息
217 | cout << "物理地址为:" << setw(3)<runTime; } //返回运行次数
244 | int getAdjustTime() { return this->adjustTime; } //返回调页次数
245 | double getAdjustRate(){ return (1.0*this->adjustTime / this->runTime); } //返回缺页率
246 | };
247 | ```
248 |
249 |
250 |
251 | ### 实体设计
252 |
253 | 1. **指令号:** `typedef int InstNum;`
254 |
255 | 2. **页号:** `typedef int PageNum;`
256 |
257 | 3. **块号:** `typedef int BlockNum;`
258 |
259 |
260 |
261 | ### 状态设计
262 |
263 | 2. **分配给作业的总内存块数:** `#define MaxSize 4 `
264 | 2. **内存块为空标识:** `#define EMPTY -1`
265 | 3. **指令总条数:** `#define TOTALNUM 320`
266 |
267 |
268 |
269 | ## 系统实现
270 |
271 | ### 请求调页存储管理方式模拟
272 |
273 | #### 执行前320条指令
274 |
275 | - 设置变量`cnt`用于记录当前已执行的指令条数, 初始化为0
276 |
277 | - 随机选取一个起始指令 => 递增`cnt` => 顺序执行下一条指令 => 递增`cnt`
278 |
279 | - 进入循环:
280 |
281 | - 判断是否执行满320条指令(cnt是否为320) => 跳转到前地址部分 => 递增`cnt`
282 | - 判断是否执行满320条指令 => 顺序执行下一条指令 => 递增`cnt`
283 | - 判断是否执行满320条指令 => 跳转到后地址部分 => 递增`cnt`
284 | - 判断是否执行满320条指令 => 顺序执行下一条指令 => 递增`cnt`
285 |
286 | #### 执行完所有指令
287 |
288 | - 设置变量`restInst`用于记录剩余未执行指令数, 初始化为320
289 |
290 | - 设置布尔向量`visited`用于记录是否执行过该指令, 初始化为false
291 |
292 | - 随机选取一个起始指令 => 递减`restInst` => `visited`中标记为true => 顺序执行下一条指令 => 递减`restInst` => `visited`中标记为true
293 |
294 | - 进入循环:
295 |
296 | - 判断是否执行完所有指令(`restInst`是否为0) => 跳转到前地址部分 => 递减`restInst` => `visited`中标记为true
297 | - 判断是否执行完所有指令 => 顺序执行下一条指令 => 递减`restInst` => `visited`中标记为true
298 | - 判断是否执行完所有指令 => 跳转到后地址部分 => 递减`restInst` => `visited`中标记为true
299 | - 判断是否执行完所有指令 => 顺序执行下一条指令 => 递减`restInst` => `visited`中标记为true
300 |
301 | ```c++
302 | /* 请求调页存储管理方式模拟
303 | * @param {置换算法} algorithm
304 | * @param {用户选择的执行类型} type
305 | */
306 | void Memory::Simulate(string algorithm, char type)
307 | {
308 | InstNum aim;
309 | if (type == 'A' || type == 'a')
310 | {
311 | int cnt = 0;
312 |
313 | //随机选取一个起始指令
314 | aim = getRand(0, TOTALNUM - 1);
315 | execute(algorithm, aim); cnt++;
316 | //顺序执行下一条指令
317 | aim++;
318 | execute(algorithm, aim); cnt++;
319 | while (true)
320 | {
321 | if (cnt == TOTALNUM) { break; }
322 | //跳转到前地址部分
323 | aim = getRand(0, aim - 1);
324 | execute(algorithm, aim); cnt++;
325 |
326 | if (cnt == TOTALNUM) { break; }
327 | //顺序执行下一条指令
328 | aim++;
329 | execute(algorithm, aim); cnt++;
330 |
331 | if (cnt == TOTALNUM) { break; }
332 | //跳转到后地址部分
333 | aim = getRand(aim + 1, TOTALNUM - 1);
334 | execute(algorithm, aim); cnt++;
335 |
336 | if (cnt == TOTALNUM) { break; }
337 | //顺序执行下一条指令
338 | aim++;
339 | execute(algorithm, aim); cnt++;
340 | }
341 | }
342 | else if (type == 'B' || type == 'b')
343 | {
344 | //随机选取一个起始指令
345 | aim = getRand(0, TOTALNUM - 1);
346 | execute(algorithm, aim);
347 | restInst--; visited[aim] = true;
348 | //顺序执行下一条指令
349 | aim++;
350 | execute(algorithm, aim);
351 | restInst--; visited[aim] = true;
352 |
353 | while (true)
354 | {
355 | if (!restInst) { break; }
356 | //跳转到前地址部分
357 | aim = getRand(0, aim - 1);
358 | execute(algorithm, aim);
359 | if (aim!=TOTALNUM && !visited[aim]) { restInst--; visited[aim] = true; }
360 |
361 | if (!restInst) { break; }
362 | //顺序执行下一条指令
363 | aim++;
364 | execute(algorithm, aim);
365 | if (aim != TOTALNUM && !visited[aim]) { restInst--; visited[aim] = true; }
366 |
367 | if (!restInst) { break; }
368 | //跳转到后地址部分
369 | aim = getRand(aim + 1, TOTALNUM - 1);
370 | execute(algorithm, aim);
371 | if (aim != TOTALNUM && !visited[aim]) { restInst--; visited[aim] = true; }
372 |
373 | if (!restInst) { break; }
374 | //顺序执行下一条指令
375 | aim++;
376 | execute(algorithm, aim);
377 | if (aim != TOTALNUM && !visited[aim]) { restInst--; visited[aim] = true; }
378 | }
379 | }
380 | }
381 | ```
382 |
383 |
384 |
385 | ### 执行一条指令
386 |
387 | - 更新运行次数
388 | - 计算页号并输出该指令的信息(物理地址, 页号, 页内地址)
389 | - 检测该页是否已经在内存中:
390 | - 如果是 => 打印已经在内存块中相应信息
391 | - 检测内存中有无空闲块:
392 | - 如果有 => 打印没在内存块中, 但是内存块没满相应信息
393 | - 按照相应的算法请求调页
394 |
395 | ```c++
396 | /* 执行一条指令
397 | * @param {置换算法} algorithm
398 | * @param {待执行指令} aim
399 | */
400 | void Memory::execute(string algorithm, InstNum aim)
401 | {
402 | this->runTime++; //更新运行次数
403 |
404 | PageNum page = aim / 10; //计算页号
405 | BlockNum pos = 0;
406 |
407 | displayPosMess(aim);
408 |
409 | /*检测该页是否已经在内存中*/
410 | for (pos = 0; pos < MaxSize; ++pos)
411 | {
412 | if (block[pos] == page)
413 | {
414 | displayLoadMess(page, pos, true);
415 |
416 | return;
417 | }
418 | }
419 | /*检测内存中有无空闲块*/
420 | for (pos = 0; pos < MaxSize; ++pos)
421 | {
422 | if (block[pos] == EMPTY)
423 | {
424 | block[pos] = page;
425 | displayLoadMess(page, pos, false);
426 |
427 | if (algorithm == string("LRU"))
428 | {
429 | LRU_Queue.push(pos); //将其压入最近最少使用队列
430 | }
431 |
432 | return;
433 | }
434 | }
435 |
436 | //执行到这说明: 1.内存块是满的 2.要进行调页
437 | PageNum old = adjust(algorithm, pos);
438 | block[pos] = page;
439 | displayLoadMess(old, page, pos);
440 | }
441 | ```
442 |
443 |
444 |
445 | ### 请求调页
446 |
447 | - 更新调页次数
448 | - FIFO算法:
449 | - 根据缺页次数计算哪个页面要被替换掉, 位置记录在`pos`中
450 | - 内存块中`pos`位置页面记录为`old`
451 | - LRU算法:
452 | - 访问LRU队列头, 获取最近最少使用页面位置, 记录在`pos`中
453 | - 将该位置填入新的页面
454 | - 压入队列尾
455 |
456 | ```c++
457 | /* 请求调页
458 | * @returnValue {要被替换掉的页号}
459 | * @param {置换算法} algorithm
460 | * @param {调入调出的位置} pos
461 | */
462 | PageNum Memory::adjust(string algorithm, BlockNum &pos)
463 | {
464 | this->adjustTime++; //更新调页次数
465 |
466 | PageNum old;
467 | if (algorithm == "FIFO")
468 | {
469 | pos = (this->adjustTime-1) % 4; //缺页次数为1, 则将0号内存的页调出, 将当前指令调入0 号内存中...以此类推
470 | old = block[pos];
471 | }
472 | else if (algorithm == "LRU")
473 | {
474 | pos = LRU_Queue.front(); //取队列头元素 => 最近最少使用的页面
475 | LRU_Queue.pop();
476 | LRU_Queue.push(pos); //将其压入队尾
477 |
478 | old = block[pos];
479 | }
480 |
481 | return old;
482 | }
483 | ```
484 |
485 | ### 打印信息
486 |
487 | - 打印指令的物理地址, 页面, 页内地址
488 | - 打印未发生调页的信息
489 | - 打印发生调页的信息
490 |
491 | ```c++
492 | void displayPosMess(InstNum aim) { //打印指令地址信息
493 | cout << "物理地址为:" << setw(3)<
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/文件管理_文件管理模拟系统/FileManageSystem.pdb:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/doubleZ0108/Operating-System/f00305ef02f4c4b7a92252947dcd559e7602c434/文件管理_文件管理模拟系统/FileManageSystem.pdb
--------------------------------------------------------------------------------
/文件管理_文件管理模拟系统/MyControl.dll:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/doubleZ0108/Operating-System/f00305ef02f4c4b7a92252947dcd559e7602c434/文件管理_文件管理模拟系统/MyControl.dll
--------------------------------------------------------------------------------
/文件管理_文件管理模拟系统/MyControl.pdb:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/doubleZ0108/Operating-System/f00305ef02f4c4b7a92252947dcd559e7602c434/文件管理_文件管理模拟系统/MyControl.pdb
--------------------------------------------------------------------------------
/文件管理_文件管理模拟系统/MyDiskInfo.txt:
--------------------------------------------------------------------------------
1 | #
2 | #
3 | #
4 | #
5 | #
6 | #
7 | #
8 | #
9 | #
10 | #
11 | #
12 | #
13 | #
14 | #
15 | #
16 | #
17 | #
18 | #
19 | #
20 | #
21 | #
22 | #
23 | #
24 | #
25 | #
26 | #
27 | #
28 | #
29 | #
30 | #
31 | #
32 | #
33 | #
34 | #
35 | #
36 | #
37 | #
38 | #
39 | #
40 | #
41 | #
42 | #
43 | #
44 | #
45 | #
46 | #
47 | #
48 | #
49 | #
50 | #
51 | #
52 | #
53 | #
54 | #
55 | #
56 | #
57 | #
58 | #
59 | #
60 | #
61 | #
62 | #
63 | #
64 | #
65 | #
66 | #
67 | #
68 | #
69 | #
70 | #
71 | #
72 | #
73 | #
74 | #
75 | #
76 | #
77 | #
78 | #
79 | #
80 | #
81 | #
82 | #
83 | #
84 | #
85 | #
86 | #
87 | #
88 | #
89 | #
90 | #
91 | #
92 | #
93 | #
94 | #
95 | #
96 | #
97 | #
98 | #
99 | #
100 | #
101 | #
102 | #
103 | #
104 | #
105 | #
106 | #
107 | #
108 | #
109 | #
110 | #
111 | #
112 | #
113 | #
114 | #
115 | #
116 | #
117 | #
118 | #
119 | #
120 | #
121 | #
122 | #
123 | #
124 | #
125 | #
126 | #
127 | #
128 | #
129 | #
130 | #
131 | #
132 | #
133 | #
134 | #
135 | #
136 | #
137 | #
138 | #
139 | #
140 | #
141 | #
142 | #
143 | #
144 | #
145 | #
146 | #
147 | #
148 | #
149 | #
150 | #
151 | #
152 | #
153 | #
154 | #
155 | #
156 | #
157 | #
158 | #
159 | #
160 | #
161 | #
162 | #
163 | #
164 | #
165 | #
166 | #
167 | #
168 | #
169 | #
170 | #
171 | #
172 | #
173 | #
174 | #
175 | #
176 | #
177 | #
178 | #
179 | #
180 | #
181 | #
182 | #
183 | #
184 | #
185 | #
186 | #
187 | #
188 | #
189 | #
190 | #
191 | #
192 | #
193 | #
194 | #
195 | #
196 | #
197 | #
198 | #
199 | #
200 | #
201 | #
202 | #
203 | #
204 | #
205 | #
206 | #
207 | #
208 | #
209 | #
210 | #
211 | #
212 | #
213 | #
214 | #
215 | #
216 | #
217 | #
218 | #
219 | #
220 | #
221 | #
222 | #
223 | #
224 | #
225 | #
226 | #
227 | #
228 | #
229 | #
230 | #
231 | #
232 | #
233 | #
234 | #
235 | #
236 | #
237 | #
238 | #
239 | #
240 | #
241 | #
242 | #
243 | #
244 | #
245 | #
246 | #
247 | #
248 | #
249 | #
250 | #
251 | #
252 | #
253 | #
254 | #
255 | #
256 | #
257 | #
258 | #
259 | #
260 | #
261 | #
262 | #
263 | #
264 | #
265 | #
266 | #
267 | #
268 | #
269 | #
270 | #
271 | #
272 | #
273 | #
274 | #
275 | #
276 | #
277 | #
278 | #
279 | #
280 | #
281 | #
282 | #
283 | #
284 | #
285 | #
286 | #
287 | #
288 | #
289 | #
290 | #
291 | #
292 | #
293 | #
294 | #
295 | #
296 | #
297 | #
298 | #
299 | #
300 | #
301 | #
302 | #
303 | #
304 | #
305 | #
306 | #
307 | #
308 | #
309 | #
310 | #
311 | #
312 | #
313 | #
314 | #
315 | #
316 | #
317 | #
318 | #
319 | #
320 | #
321 | #
322 | #
323 | #
324 | #
325 | #
326 | #
327 | #
328 | #
329 | #
330 | #
331 | #
332 | #
333 | #
334 | #
335 | #
336 | #
337 | #
338 | #
339 | #
340 | #
341 | #
342 | #
343 | #
344 | #
345 | #
346 | #
347 | #
348 | #
349 | #
350 | #
351 | #
352 | #
353 | #
354 | #
355 | #
356 | #
357 | #
358 | #
359 | #
360 | #
361 | #
362 | #
363 | #
364 | #
365 | #
366 | #
367 | #
368 | #
369 | #
370 | #
371 | #
372 | #
373 | #
374 | #
375 | #
376 | #
377 | #
378 | #
379 | #
380 | #
381 | #
382 | #
383 | #
384 | #
385 | #
386 | #
387 | #
388 | #
389 | #
390 | #
391 | #
392 | #
393 | #
394 | #
395 | #
396 | #
397 | #
398 | #
399 | #
400 | #
401 | #
402 | #
403 | #
404 | #
405 | #
406 | #
407 | #
408 | #
409 | #
410 | #
411 | #
412 | #
413 | #
414 | #
415 | #
416 | #
417 | #
418 | #
419 | #
420 | #
421 | #
422 | #
423 | #
424 | #
425 | #
426 | #
427 | #
428 | #
429 | #
430 | #
431 | #
432 | #
433 | #
434 | #
435 | #
436 | #
437 | #
438 | #
439 | #
440 | #
441 | #
442 | #
443 | #
444 | #
445 | #
446 | #
447 | #
448 | #
449 | #
450 | #
451 | #
452 | #
453 | #
454 | #
455 | #
456 | #
457 | #
458 | #
459 | #
460 | #
461 | #
462 | #
463 | #
464 | #
465 | #
466 | #
467 | #
468 | #
469 | #
470 | #
471 | #
472 | #
473 | #
474 | #
475 | #
476 | #
477 | #
478 | #
479 | #
480 | #
481 | #
482 | #
483 | #
484 | #
485 | #
486 | #
487 | #
488 | #
489 | #
490 | #
491 | #
492 | #
493 | #
494 | #
495 | #
496 | #
497 | #
498 | #
499 | #
500 | #
501 |
--------------------------------------------------------------------------------
/文件管理_文件管理模拟系统/README.md:
--------------------------------------------------------------------------------
1 | # 文件管理 - 文件系统
2 |
3 | ###### 操作系统第三次课程作业 - 文件系统
4 |
5 | ❗❗❗ 请勿删除可执行程序目录下的`BitMapInfo.txt` ,`CategoryInfo.txt `, `MyDiskInfo.txt`, 及其他配置文件, 否则可能导致文件系统无法正常运行❗❗❗
6 |
7 | ## 目录
8 |
9 | - [开发环境](#开发环境)
10 | - [操作说明](#操作说明)
11 | - [项目结构](#项目结构)
12 | - [作者](#作者)
13 |
14 |
15 |
16 | ## 开发环境
17 |
18 | - **开发环境:** Windows 10
19 |
20 | - **开发软件:**
21 |
22 | **Visual Studio 2017** *15.9.28307.665*
23 |
24 | - **开发语言:** C#
25 |
26 |
27 |
28 |
29 | ## 操作说明
30 |
31 | - 双击目录下`FileManagementSystem.exe`可执行文件进入文件系统模拟界面
32 |
33 | 
34 |
35 | - 请详细阅读**操作帮助**了解模拟器功能, 点击`我知道了`关闭**帮助信息窗口**
36 |
37 | - 单击**鼠标右键**, 新建文件夹/新建文件
38 |
39 | 
40 |
41 | - 您也可以点击**右侧按钮**进行创建文件夹/文本文件
42 |
43 | 
44 |
45 | - 输入文件夹名或文件名, 即可在目录中查看到创建的文件夹/文件
46 |
47 | 
48 |
49 | 
50 |
51 | - 在文件夹/文件上点击鼠标右键可选择打开/删除
52 |
53 | 
54 |
55 | - **单击文件夹**可进入下一级文件夹, 上方可查看**当前文件路径**
56 |
57 | 
58 |
59 | - **单击文件**可打开**编辑窗口**, 编辑完成后点击右上角的`X`, *确定以保存, 取消则直接退出*
60 |
61 | 
62 |
63 | - 可查看**文件相应信息**(文件名, 上次修改日期, 文件大小*(自定义单位)*)
64 |
65 | 
66 |
67 | - 左侧的**目录树**可点击展开, 以查看当前目录结构
68 |
69 | 
70 |
71 | - **双击目录树**中的文件夹打开文件夹, 双击目录树中的文件可打开文件进行浏览和编辑
72 |
73 | - 点击**返回上级目录**可跳转到上级文件夹, 在root文件夹时无法返回
74 |
75 | 
76 |
77 | - 点击右侧**格式化**并再次确定可清空磁盘, 系统会清空所有文件夹和文本文件, 并清空目录树
78 |
79 | 
80 |
81 | - ❗❗❗受展示限制, 本文件系统模拟器在一个目录下最多可创建8个子项目, 超过8个时会受到系统提醒*(只是受展示方式限制, 物理和逻辑上的存储理论上都允许创建无限多的子项目)*
82 |
83 | 
84 |
85 |
86 |
87 | ## 项目结构
88 | ```
89 | │ BitMapInfo.txt
90 | │ CategoryInfo.txt
91 | │ FileManageSystem.exe
92 | │ FileManageSystem.exe.config
93 | │ FileManageSystem.pdb
94 | │ MyControl.dll
95 | │ MyControl.pdb
96 | │ MyDiskInfo.txt
97 | │ README.md
98 | │ 文件管理系统_设计方案报告.md
99 | │ 文件管理系统_设计方案报告.pdf
100 | │
101 | ├─Resources
102 | │ │ file18.png
103 | │ │ file25.png
104 | │ │ fileopen48.ico
105 | │ │ folder18.png
106 | │ │ folder25.png
107 | │ │
108 | │ └─icon
109 | │ help.ico
110 | │ icon.ico
111 | │ note.ico
112 | │
113 | └─src
114 | │ Category.cs
115 | │ FCB.cs
116 | │ Program.cs
117 | │ VirtualDisk.cs
118 | │
119 | └─Form
120 | ├─HelpForm
121 | │ HelpForm.cs
122 | │ HelpForm.Designer.cs
123 | │ HelpForm.resx
124 | │
125 | ├─MainForm
126 | │ MainForm.cs
127 | │ MainForm.Designer.cs
128 | │ MainForm.resx
129 | │
130 | └─NoteForm
131 | NoteForm.cs
132 | NoteForm.Designer.cs
133 | NoteForm.resx
134 | ```
135 |
136 |
137 |
138 | #### 作者
139 |
140 | **学号** 1754060
141 |
142 | **姓名** 张喆
143 |
144 | **指导老师** 王冬青老师
145 |
146 | **上课时间** 周三/周五 上午一二节
147 |
148 | **联系方式** *email:* doubleZ0108@gmail.com
149 |
--------------------------------------------------------------------------------
/文件管理_文件管理模拟系统/Resources/file18.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/doubleZ0108/Operating-System/f00305ef02f4c4b7a92252947dcd559e7602c434/文件管理_文件管理模拟系统/Resources/file18.png
--------------------------------------------------------------------------------
/文件管理_文件管理模拟系统/Resources/file25.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/doubleZ0108/Operating-System/f00305ef02f4c4b7a92252947dcd559e7602c434/文件管理_文件管理模拟系统/Resources/file25.png
--------------------------------------------------------------------------------
/文件管理_文件管理模拟系统/Resources/fileopen48.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/doubleZ0108/Operating-System/f00305ef02f4c4b7a92252947dcd559e7602c434/文件管理_文件管理模拟系统/Resources/fileopen48.ico
--------------------------------------------------------------------------------
/文件管理_文件管理模拟系统/Resources/folder18.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/doubleZ0108/Operating-System/f00305ef02f4c4b7a92252947dcd559e7602c434/文件管理_文件管理模拟系统/Resources/folder18.png
--------------------------------------------------------------------------------
/文件管理_文件管理模拟系统/Resources/folder25.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/doubleZ0108/Operating-System/f00305ef02f4c4b7a92252947dcd559e7602c434/文件管理_文件管理模拟系统/Resources/folder25.png
--------------------------------------------------------------------------------
/文件管理_文件管理模拟系统/Resources/icon/help.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/doubleZ0108/Operating-System/f00305ef02f4c4b7a92252947dcd559e7602c434/文件管理_文件管理模拟系统/Resources/icon/help.ico
--------------------------------------------------------------------------------
/文件管理_文件管理模拟系统/Resources/icon/icon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/doubleZ0108/Operating-System/f00305ef02f4c4b7a92252947dcd559e7602c434/文件管理_文件管理模拟系统/Resources/icon/icon.ico
--------------------------------------------------------------------------------
/文件管理_文件管理模拟系统/Resources/icon/note.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/doubleZ0108/Operating-System/f00305ef02f4c4b7a92252947dcd559e7602c434/文件管理_文件管理模拟系统/Resources/icon/note.ico
--------------------------------------------------------------------------------
/文件管理_文件管理模拟系统/src/Category.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Text;
5 | using System.Threading.Tasks;
6 |
7 | namespace FileManageSystem
8 | {
9 | public class Category
10 | {
11 | //目录节点
12 | public class Node
13 | {
14 | //节点存储的数据
15 | public FCB fcb = new FCB();
16 |
17 | public Node firstChild = null; //左孩子
18 | public Node nextBrother = null; //右兄弟
19 | public Node parent = null; //父结点
20 |
21 | public Node() { }
22 | public Node(FCB file)
23 | {
24 | fcb.fileName = file.fileName;
25 | fcb.lastModify = file.lastModify;
26 | fcb.type = file.type;
27 | fcb.size = file.size;
28 | }
29 | public Node(string name, int type)
30 | {
31 | fcb.fileName = name;
32 | fcb.type = type;
33 | }
34 | }
35 |
36 | public Node root; //目录的根节点
37 |
38 |
39 | public Category()
40 | {
41 | root = null;
42 | }
43 | public Category(FCB rootName)
44 | {
45 | root = new Node(rootName);
46 | if (root == null)
47 | { return; }
48 | }
49 |
50 | /*清空某目录(当参数为root是为格式化)*/
51 | public void freeCategory(Node pNode)
52 | {
53 | if (pNode == null)
54 | { return; }
55 |
56 | if (pNode.firstChild != null) //清空左孩子
57 | {
58 | freeCategory(pNode.firstChild);
59 | pNode.firstChild = null;
60 | }
61 | if (pNode.nextBrother != null) //清空右兄弟
62 | {
63 | freeCategory(pNode.nextBrother);
64 | pNode.nextBrother = null;
65 | }
66 |
67 | pNode = null; //将自己清除
68 | }
69 |
70 | /*删掉结点*/
71 | public void delete(Node pNode)
72 | {
73 | pNode = null;
74 | }
75 |
76 | /*搜索文件*/
77 | public Node search(Node pNode, string fileName, int type)
78 | {
79 | if (pNode == null)
80 | { return null; }
81 | if (pNode.fcb.fileName == fileName && pNode.fcb.type == type)
82 | { return pNode; }
83 | if (pNode.firstChild == null && pNode.nextBrother == null)
84 | { return null; }
85 | else
86 | {
87 | Node firstChild = search(pNode.firstChild, fileName, type); //递归的搜索左孩子的子树
88 | if (firstChild != null)
89 | { return firstChild; }
90 | else
91 | { return search(pNode.nextBrother, fileName, type); } //递归的搜索右兄弟的子树
92 | }
93 | }
94 |
95 | /*在文件夹中创建文件*/
96 | public void createFile(string parentFileName, FCB file)
97 | {
98 | if (root == null)
99 | { return; }
100 | Node parentNode = search(root, parentFileName, FCB.FOLDER); //找到父文件夹
101 |
102 | if (parentNode == null)
103 | { return; }
104 | if (parentNode.firstChild == null) //该文件夹为空
105 | {
106 | parentNode.firstChild = new Node(file); //新创建的文件为第一个文件, 放到左孩子的位置
107 | parentNode.firstChild.parent = parentNode;
108 | return;
109 | }
110 | else
111 | {
112 | Node temp = parentNode.firstChild;
113 | while (temp.nextBrother != null) //顺序找到该文件夹下最后一个文件存储的位置
114 | temp = temp.nextBrother;
115 |
116 | temp.nextBrother = new Node(file);
117 | temp.nextBrother.parent = parentNode;
118 |
119 | }
120 | }
121 |
122 | /*删除文件夹*/
123 | public void deleteFolder(string name)
124 | {
125 | Node currentNode = search(root, name, FCB.FOLDER); //找到要删除的结点
126 | Node parentNode = currentNode.parent;
127 |
128 | if (parentNode.firstChild == currentNode) //如果要删除的文件夹是父文件夹中的第一项
129 | { parentNode.firstChild = currentNode.nextBrother; } //更新父文件夹的左孩子
130 | else
131 | {
132 | Node temp = parentNode.firstChild;
133 | while (temp.nextBrother != currentNode)
134 | {
135 | temp = temp.nextBrother;
136 | }
137 |
138 | temp.nextBrother = currentNode.nextBrother; //找到该文件的哥哥, 让其指向自己的弟弟
139 | }
140 |
141 | freeCategory(currentNode); //删除当前结点下的所有文件
142 | }
143 |
144 | /*删除文件*/
145 | public void deleteFile(string name)
146 | {
147 | Node currentNode = search(root, name, FCB.TXTFILE); //找到要删除的文件
148 | Node parentNode = currentNode.parent;
149 |
150 | if (parentNode.firstChild == currentNode) //如果要删除的文件是父文件夹中的第一项
151 | { parentNode.firstChild = currentNode.nextBrother; } //更新父文件夹的左孩子
152 | else
153 | {
154 | Node temp = parentNode.firstChild;
155 | while (temp.nextBrother != currentNode)
156 | {
157 | temp = temp.nextBrother;
158 | }
159 |
160 | temp.nextBrother = currentNode.nextBrother;
161 | }
162 | currentNode = null;
163 | }
164 |
165 | /*判断同级目录下是否重名*/
166 | public bool noSameName(string name, Node pNode, int type)
167 | {
168 | //pNode为该级目录的根节点
169 | pNode = pNode.firstChild;
170 | if (pNode == null) //该目录中无任何文件夹和文件
171 | { return true; }
172 | if (pNode.fcb.fileName == name && pNode.fcb.type == type) //第一个文件夹/文件重名
173 | { return false; }
174 | else
175 | {
176 | Node temp = pNode.nextBrother;
177 | while (temp != null)
178 | {
179 | if (temp.fcb.fileName == name && temp.fcb.type == type)
180 | { return false; }
181 | temp = pNode.nextBrother;
182 | }
183 | return true; //不重名
184 | }
185 | }
186 |
187 | /*寻找该目录下根目录的名称*/
188 | public Node currentRootName(Node pNode, string name, int type)
189 | {
190 | if (pNode == null)
191 | { return null; }
192 | if (pNode.firstChild == null)
193 | { return null; }
194 | else
195 | {
196 | if (pNode.firstChild.fcb.fileName == name && pNode.firstChild.fcb.type == type)
197 | { return pNode; }
198 | else
199 | {
200 | Node par = pNode;
201 | Node temp = pNode.firstChild.nextBrother;
202 | while (temp != null)
203 | {
204 | if (temp.fcb.fileName == name && temp.fcb.type == type)
205 | { return par; }
206 | else
207 | { temp = temp.nextBrother; }
208 | }
209 | if (currentRootName(par.firstChild, name, type) != null) //递归地在左孩子子树中寻找
210 | {
211 | return currentRootName(par.firstChild, name, type);
212 | }
213 | else
214 | {
215 | return currentRootName(par.firstChild.nextBrother, name, type); //递归地在右兄弟子树中寻找
216 | }
217 | }
218 | }
219 | }
220 | }
221 | }
222 |
--------------------------------------------------------------------------------
/文件管理_文件管理模拟系统/src/FCB.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Text;
5 | using System.Threading.Tasks;
6 |
7 | namespace FileManageSystem
8 | {
9 | //目录项
10 | public class FCB
11 | {
12 | public const int TXTFILE = 0; //文本文件标识
13 | public const int FOLDER = 1; //文件夹标识
14 |
15 | public string fileName; //文件名
16 | public int start; //文件在内存中初始存放的位置
17 | public int type; //文件类型 => TXTDILE/FOLDER
18 | public string lastModify; //最近修改时间
19 | public int size; //文件大小,文件夹不显示大小
20 |
21 | public FCB() { }
22 | public FCB(string name,int type, string time, int size)
23 | {
24 | this.fileName = name;
25 | this.type = type;
26 | this.lastModify = time;
27 | this.size = size;
28 | }
29 | public FCB(string name, int type, string time, int size,int start)
30 | {
31 | this.fileName = name;
32 | this.type = type;
33 | this.lastModify = time;
34 | this.size = size;
35 | this.start = start;
36 | }
37 | }
38 | }
39 |
--------------------------------------------------------------------------------
/文件管理_文件管理模拟系统/src/Form/HelpForm/HelpForm.Designer.cs:
--------------------------------------------------------------------------------
1 | namespace File_Management_System
2 | {
3 | partial class HelpForm
4 | {
5 | ///
6 | /// Required designer variable.
7 | ///
8 | private System.ComponentModel.IContainer components = null;
9 |
10 | ///
11 | /// Clean up any resources being used.
12 | ///
13 | /// true if managed resources should be disposed; otherwise, false.
14 | protected override void Dispose(bool disposing)
15 | {
16 | if (disposing && (components != null))
17 | {
18 | components.Dispose();
19 | }
20 | base.Dispose(disposing);
21 | }
22 |
23 | #region Windows Form Designer generated code
24 |
25 | ///
26 | /// Required method for Designer support - do not modify
27 | /// the contents of this method with the code editor.
28 | ///
29 | private void InitializeComponent()
30 | {
31 | System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(HelpForm));
32 | this.textBox1 = new System.Windows.Forms.TextBox();
33 | this.textBox2 = new System.Windows.Forms.TextBox();
34 | this.textBox3 = new System.Windows.Forms.TextBox();
35 | this.textBox4 = new System.Windows.Forms.TextBox();
36 | this.textBox5 = new System.Windows.Forms.TextBox();
37 | this.textBox6 = new System.Windows.Forms.TextBox();
38 | this.textBox7 = new System.Windows.Forms.TextBox();
39 | this.textBox8 = new System.Windows.Forms.TextBox();
40 | this.textBox9 = new System.Windows.Forms.TextBox();
41 | this.button1 = new System.Windows.Forms.Button();
42 | this.SuspendLayout();
43 | //
44 | // textBox1
45 | //
46 | this.textBox1.BackColor = System.Drawing.SystemColors.Menu;
47 | this.textBox1.BorderStyle = System.Windows.Forms.BorderStyle.None;
48 | this.textBox1.Location = new System.Drawing.Point(86, 103);
49 | this.textBox1.Name = "textBox1";
50 | this.textBox1.Size = new System.Drawing.Size(487, 21);
51 | this.textBox1.TabIndex = 0;
52 | this.textBox1.Text = "1. 您可以单击鼠标右键『新建文件夹』或『新建文本文件』";
53 | this.textBox1.TextChanged += new System.EventHandler(this.textBox1_TextChanged);
54 | //
55 | // textBox2
56 | //
57 | this.textBox2.BackColor = System.Drawing.SystemColors.Menu;
58 | this.textBox2.BorderStyle = System.Windows.Forms.BorderStyle.None;
59 | this.textBox2.Location = new System.Drawing.Point(86, 140);
60 | this.textBox2.Name = "textBox2";
61 | this.textBox2.Size = new System.Drawing.Size(487, 21);
62 | this.textBox2.TabIndex = 0;
63 | this.textBox2.Text = "1. 您可以单击鼠标右键『新建文件夹』或『新建文本文件』";
64 | this.textBox2.TextChanged += new System.EventHandler(this.textBox1_TextChanged);
65 | //
66 | // textBox3
67 | //
68 | this.textBox3.BackColor = System.Drawing.SystemColors.Menu;
69 | this.textBox3.BorderStyle = System.Windows.Forms.BorderStyle.None;
70 | this.textBox3.Location = new System.Drawing.Point(86, 214);
71 | this.textBox3.Name = "textBox3";
72 | this.textBox3.Size = new System.Drawing.Size(487, 21);
73 | this.textBox3.TabIndex = 0;
74 | this.textBox3.Text = "4. 左侧的目录树中单击『展开文件夹』或双击『打开文件』";
75 | this.textBox3.TextChanged += new System.EventHandler(this.textBox1_TextChanged);
76 | //
77 | // textBox4
78 | //
79 | this.textBox4.BackColor = System.Drawing.SystemColors.Menu;
80 | this.textBox4.BorderStyle = System.Windows.Forms.BorderStyle.None;
81 | this.textBox4.Location = new System.Drawing.Point(86, 178);
82 | this.textBox4.Name = "textBox4";
83 | this.textBox4.Size = new System.Drawing.Size(487, 21);
84 | this.textBox4.TabIndex = 0;
85 | this.textBox4.Text = "3. 搜索框中输入文件夹或以.txt为后缀的文件名进行『搜索』";
86 | this.textBox4.TextChanged += new System.EventHandler(this.textBox1_TextChanged);
87 | //
88 | // textBox5
89 | //
90 | this.textBox5.BackColor = System.Drawing.SystemColors.Menu;
91 | this.textBox5.BorderStyle = System.Windows.Forms.BorderStyle.None;
92 | this.textBox5.Font = new System.Drawing.Font("黑体", 22F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(134)));
93 | this.textBox5.Location = new System.Drawing.Point(235, 25);
94 | this.textBox5.Name = "textBox5";
95 | this.textBox5.Size = new System.Drawing.Size(186, 51);
96 | this.textBox5.TabIndex = 0;
97 | this.textBox5.Text = "操作帮助";
98 | this.textBox5.TextChanged += new System.EventHandler(this.textBox1_TextChanged);
99 | //
100 | // textBox6
101 | //
102 | this.textBox6.BackColor = System.Drawing.SystemColors.Menu;
103 | this.textBox6.BorderStyle = System.Windows.Forms.BorderStyle.None;
104 | this.textBox6.Location = new System.Drawing.Point(86, 140);
105 | this.textBox6.Name = "textBox6";
106 | this.textBox6.Size = new System.Drawing.Size(537, 21);
107 | this.textBox6.TabIndex = 0;
108 | this.textBox6.Text = "2. 双击打开文件或文件夹, 或通过右键进行『打开』和『删除』";
109 | this.textBox6.TextChanged += new System.EventHandler(this.textBox1_TextChanged);
110 | //
111 | // textBox7
112 | //
113 | this.textBox7.BackColor = System.Drawing.SystemColors.Menu;
114 | this.textBox7.BorderStyle = System.Windows.Forms.BorderStyle.None;
115 | this.textBox7.Location = new System.Drawing.Point(86, 255);
116 | this.textBox7.Name = "textBox7";
117 | this.textBox7.Size = new System.Drawing.Size(537, 21);
118 | this.textBox7.TabIndex = 0;
119 | this.textBox7.Text = "5. 选择右侧的按钮进行『格式化』, 同时您也可以『新建文件夹』\r\n";
120 | this.textBox7.TextChanged += new System.EventHandler(this.textBox1_TextChanged);
121 | //
122 | // textBox8
123 | //
124 | this.textBox8.BackColor = System.Drawing.SystemColors.Menu;
125 | this.textBox8.BorderStyle = System.Windows.Forms.BorderStyle.None;
126 | this.textBox8.Location = new System.Drawing.Point(113, 279);
127 | this.textBox8.Name = "textBox8";
128 | this.textBox8.Size = new System.Drawing.Size(130, 21);
129 | this.textBox8.TabIndex = 0;
130 | this.textBox8.Text = "和『新建文件』";
131 | this.textBox8.TextChanged += new System.EventHandler(this.textBox1_TextChanged);
132 | //
133 | // textBox9
134 | //
135 | this.textBox9.BackColor = System.Drawing.SystemColors.Menu;
136 | this.textBox9.BorderStyle = System.Windows.Forms.BorderStyle.None;
137 | this.textBox9.Location = new System.Drawing.Point(86, 306);
138 | this.textBox9.Name = "textBox9";
139 | this.textBox9.Size = new System.Drawing.Size(537, 21);
140 | this.textBox9.TabIndex = 0;
141 | this.textBox9.Text = "6. 受容量限制, 一个目录下最多可创建8个文件或者子目录";
142 | this.textBox9.TextChanged += new System.EventHandler(this.textBox1_TextChanged);
143 | //
144 | // button1
145 | //
146 | this.button1.BackColor = System.Drawing.SystemColors.ActiveCaption;
147 | this.button1.Location = new System.Drawing.Point(271, 337);
148 | this.button1.Name = "button1";
149 | this.button1.Size = new System.Drawing.Size(94, 43);
150 | this.button1.TabIndex = 1;
151 | this.button1.Text = "我知道了";
152 | this.button1.UseVisualStyleBackColor = false;
153 | this.button1.Click += new System.EventHandler(this.button1_Click);
154 | //
155 | // HelpForm
156 | //
157 | this.AutoScaleDimensions = new System.Drawing.SizeF(9F, 18F);
158 | this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
159 | this.ClientSize = new System.Drawing.Size(645, 407);
160 | this.Controls.Add(this.button1);
161 | this.Controls.Add(this.textBox6);
162 | this.Controls.Add(this.textBox4);
163 | this.Controls.Add(this.textBox8);
164 | this.Controls.Add(this.textBox9);
165 | this.Controls.Add(this.textBox7);
166 | this.Controls.Add(this.textBox3);
167 | this.Controls.Add(this.textBox5);
168 | this.Controls.Add(this.textBox2);
169 | this.Controls.Add(this.textBox1);
170 | this.Icon = ((System.Drawing.Icon)(resources.GetObject("$this.Icon")));
171 | this.Name = "HelpForm";
172 | this.Text = "帮助信息";
173 | this.Load += new System.EventHandler(this.HelpMess_Load);
174 | this.ResumeLayout(false);
175 | this.PerformLayout();
176 |
177 | }
178 |
179 | #endregion
180 |
181 | private System.Windows.Forms.TextBox textBox1;
182 | private System.Windows.Forms.TextBox textBox2;
183 | private System.Windows.Forms.TextBox textBox3;
184 | private System.Windows.Forms.TextBox textBox4;
185 | private System.Windows.Forms.TextBox textBox5;
186 | private System.Windows.Forms.TextBox textBox6;
187 | private System.Windows.Forms.TextBox textBox7;
188 | private System.Windows.Forms.TextBox textBox8;
189 | private System.Windows.Forms.TextBox textBox9;
190 | private System.Windows.Forms.Button button1;
191 | }
192 | }
--------------------------------------------------------------------------------
/文件管理_文件管理模拟系统/src/Form/HelpForm/HelpForm.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.ComponentModel;
4 | using System.Data;
5 | using System.Drawing;
6 | using System.Linq;
7 | using System.Text;
8 | using System.Threading.Tasks;
9 | using System.Windows.Forms;
10 |
11 | namespace File_Management_System
12 | {
13 | public partial class HelpForm : Form
14 | {
15 | public HelpForm()
16 | {
17 | InitializeComponent();
18 | }
19 |
20 | private void textBox1_TextChanged(object sender, EventArgs e)
21 | {
22 |
23 | }
24 |
25 | private void HelpMess_Load(object sender, EventArgs e)
26 | {
27 |
28 | }
29 |
30 | private void button1_Click(object sender, EventArgs e)
31 | {
32 | this.Close(); //点击确定关闭帮助信息窗口
33 | }
34 | }
35 | }
36 |
--------------------------------------------------------------------------------
/文件管理_文件管理模拟系统/src/Form/MainForm/MainForm.Designer.cs:
--------------------------------------------------------------------------------
1 | namespace FileManageSystem
2 | {
3 | partial class MainForm
4 | {
5 | ///
6 | /// 必需的设计器变量。
7 | ///
8 | private System.ComponentModel.IContainer components = null;
9 |
10 | ///
11 | /// 清理所有正在使用的资源。
12 | ///
13 | /// 如果应释放托管资源,为 true;否则为 false。
14 | protected override void Dispose(bool disposing)
15 | {
16 | if (disposing && (components != null))
17 | {
18 | components.Dispose();
19 | }
20 | base.Dispose(disposing);
21 | }
22 |
23 | #region Windows 窗体设计器生成的代码
24 |
25 | ///
26 | /// 设计器支持所需的方法 - 不要修改
27 | /// 使用代码编辑器修改此方法的内容。
28 | ///
29 | private void InitializeComponent()
30 | {
31 | this.components = new System.ComponentModel.Container();
32 | System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(MainForm));
33 | this.groupBox5 = new System.Windows.Forms.GroupBox();
34 | this.groupBox4 = new System.Windows.Forms.GroupBox();
35 | this.groupBox2 = new System.Windows.Forms.GroupBox();
36 | this.fileSize = new System.Windows.Forms.Label();
37 | this.fileType = new System.Windows.Forms.Label();
38 | this.modifyTime = new System.Windows.Forms.Label();
39 | this.fileName = new System.Windows.Forms.Label();
40 | this.groupBox1 = new System.Windows.Forms.GroupBox();
41 | this.groupBox3 = new System.Windows.Forms.GroupBox();
42 | this.textBoxSearch = new System.Windows.Forms.TextBox();
43 | this.groupBox6 = new System.Windows.Forms.GroupBox();
44 | this.groupBox7 = new System.Windows.Forms.GroupBox();
45 | this.contextMenuStrip1 = new System.Windows.Forms.ContextMenuStrip(this.components);
46 | this.新建文件夹ToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
47 | this.新建文件ToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
48 | this.buttonBack = new System.Windows.Forms.Button();
49 | this.buttonDelete = new System.Windows.Forms.Button();
50 | this.groupBox8 = new System.Windows.Forms.GroupBox();
51 | this.buttonCreateFolder = new System.Windows.Forms.Button();
52 | this.buttonCreateFile = new System.Windows.Forms.Button();
53 | this.labelBlockSize = new System.Windows.Forms.Label();
54 | this.labelDiskSize = new System.Windows.Forms.Label();
55 | this.fileWindow = new MyControl.UserControl1();
56 | this.groupBox9 = new System.Windows.Forms.GroupBox();
57 | this.treeView = new System.Windows.Forms.TreeView();
58 | this.imageList = new System.Windows.Forms.ImageList(this.components);
59 | this.label1 = new System.Windows.Forms.Label();
60 | this.groupBox1.SuspendLayout();
61 | this.groupBox6.SuspendLayout();
62 | this.contextMenuStrip1.SuspendLayout();
63 | this.SuspendLayout();
64 | //
65 | // groupBox5
66 | //
67 | this.groupBox5.BackColor = System.Drawing.SystemColors.ActiveBorder;
68 | this.groupBox5.Location = new System.Drawing.Point(706, 52);
69 | this.groupBox5.Margin = new System.Windows.Forms.Padding(4);
70 | this.groupBox5.Name = "groupBox5";
71 | this.groupBox5.Padding = new System.Windows.Forms.Padding(4);
72 | this.groupBox5.Size = new System.Drawing.Size(2, 36);
73 | this.groupBox5.TabIndex = 21;
74 | this.groupBox5.TabStop = false;
75 | this.groupBox5.Text = "groupBox5";
76 | //
77 | // groupBox4
78 | //
79 | this.groupBox4.BackColor = System.Drawing.SystemColors.ActiveBorder;
80 | this.groupBox4.Location = new System.Drawing.Point(891, 52);
81 | this.groupBox4.Margin = new System.Windows.Forms.Padding(4);
82 | this.groupBox4.Name = "groupBox4";
83 | this.groupBox4.Padding = new System.Windows.Forms.Padding(4);
84 | this.groupBox4.Size = new System.Drawing.Size(2, 36);
85 | this.groupBox4.TabIndex = 20;
86 | this.groupBox4.TabStop = false;
87 | this.groupBox4.Text = "groupBox4";
88 | //
89 | // groupBox2
90 | //
91 | this.groupBox2.BackColor = System.Drawing.SystemColors.ActiveBorder;
92 | this.groupBox2.Location = new System.Drawing.Point(418, 51);
93 | this.groupBox2.Margin = new System.Windows.Forms.Padding(4);
94 | this.groupBox2.Name = "groupBox2";
95 | this.groupBox2.Padding = new System.Windows.Forms.Padding(4);
96 | this.groupBox2.Size = new System.Drawing.Size(2, 36);
97 | this.groupBox2.TabIndex = 19;
98 | this.groupBox2.TabStop = false;
99 | this.groupBox2.Text = "groupBox2";
100 | //
101 | // fileSize
102 | //
103 | this.fileSize.AutoSize = true;
104 | this.fileSize.Location = new System.Drawing.Point(902, 66);
105 | this.fileSize.Margin = new System.Windows.Forms.Padding(4, 0, 4, 0);
106 | this.fileSize.Name = "fileSize";
107 | this.fileSize.Size = new System.Drawing.Size(44, 18);
108 | this.fileSize.TabIndex = 18;
109 | this.fileSize.Text = "大小";
110 | //
111 | // fileType
112 | //
113 | this.fileType.AutoSize = true;
114 | this.fileType.Location = new System.Drawing.Point(717, 66);
115 | this.fileType.Margin = new System.Windows.Forms.Padding(4, 0, 4, 0);
116 | this.fileType.Name = "fileType";
117 | this.fileType.Size = new System.Drawing.Size(44, 18);
118 | this.fileType.TabIndex = 17;
119 | this.fileType.Text = "类型";
120 | //
121 | // modifyTime
122 | //
123 | this.modifyTime.AutoSize = true;
124 | this.modifyTime.Location = new System.Drawing.Point(424, 66);
125 | this.modifyTime.Margin = new System.Windows.Forms.Padding(4, 0, 4, 0);
126 | this.modifyTime.Name = "modifyTime";
127 | this.modifyTime.Size = new System.Drawing.Size(80, 18);
128 | this.modifyTime.TabIndex = 16;
129 | this.modifyTime.Text = "修改日期";
130 | //
131 | // fileName
132 | //
133 | this.fileName.AutoSize = true;
134 | this.fileName.Location = new System.Drawing.Point(218, 66);
135 | this.fileName.Margin = new System.Windows.Forms.Padding(4, 0, 4, 0);
136 | this.fileName.Name = "fileName";
137 | this.fileName.Size = new System.Drawing.Size(62, 18);
138 | this.fileName.TabIndex = 15;
139 | this.fileName.Text = "文件名";
140 | //
141 | // groupBox1
142 | //
143 | this.groupBox1.BackColor = System.Drawing.SystemColors.ActiveBorder;
144 | this.groupBox1.Controls.Add(this.groupBox3);
145 | this.groupBox1.Location = new System.Drawing.Point(208, 50);
146 | this.groupBox1.Margin = new System.Windows.Forms.Padding(4);
147 | this.groupBox1.Name = "groupBox1";
148 | this.groupBox1.Padding = new System.Windows.Forms.Padding(4);
149 | this.groupBox1.Size = new System.Drawing.Size(852, 2);
150 | this.groupBox1.TabIndex = 14;
151 | this.groupBox1.TabStop = false;
152 | this.groupBox1.Text = "groupBox1";
153 | //
154 | // groupBox3
155 | //
156 | this.groupBox3.BackColor = System.Drawing.SystemColors.ActiveBorder;
157 | this.groupBox3.Location = new System.Drawing.Point(498, 0);
158 | this.groupBox3.Margin = new System.Windows.Forms.Padding(4);
159 | this.groupBox3.Name = "groupBox3";
160 | this.groupBox3.Padding = new System.Windows.Forms.Padding(4);
161 | this.groupBox3.Size = new System.Drawing.Size(2, 36);
162 | this.groupBox3.TabIndex = 9;
163 | this.groupBox3.TabStop = false;
164 | this.groupBox3.Text = "groupBox3";
165 | //
166 | // textBoxSearch
167 | //
168 | this.textBoxSearch.CausesValidation = false;
169 | this.textBoxSearch.Location = new System.Drawing.Point(317, 14);
170 | this.textBoxSearch.Margin = new System.Windows.Forms.Padding(4);
171 | this.textBoxSearch.Name = "textBoxSearch";
172 | this.textBoxSearch.Size = new System.Drawing.Size(508, 28);
173 | this.textBoxSearch.TabIndex = 12;
174 | this.textBoxSearch.TabStop = false;
175 | //
176 | // groupBox6
177 | //
178 | this.groupBox6.BackColor = System.Drawing.SystemColors.ActiveBorder;
179 | this.groupBox6.Controls.Add(this.groupBox7);
180 | this.groupBox6.Location = new System.Drawing.Point(208, 87);
181 | this.groupBox6.Margin = new System.Windows.Forms.Padding(4);
182 | this.groupBox6.Name = "groupBox6";
183 | this.groupBox6.Padding = new System.Windows.Forms.Padding(4);
184 | this.groupBox6.Size = new System.Drawing.Size(852, 2);
185 | this.groupBox6.TabIndex = 22;
186 | this.groupBox6.TabStop = false;
187 | this.groupBox6.Text = "groupBox6";
188 | //
189 | // groupBox7
190 | //
191 | this.groupBox7.BackColor = System.Drawing.SystemColors.ActiveBorder;
192 | this.groupBox7.Location = new System.Drawing.Point(498, 0);
193 | this.groupBox7.Margin = new System.Windows.Forms.Padding(4);
194 | this.groupBox7.Name = "groupBox7";
195 | this.groupBox7.Padding = new System.Windows.Forms.Padding(4);
196 | this.groupBox7.Size = new System.Drawing.Size(2, 36);
197 | this.groupBox7.TabIndex = 9;
198 | this.groupBox7.TabStop = false;
199 | this.groupBox7.Text = "groupBox7";
200 | //
201 | // contextMenuStrip1
202 | //
203 | this.contextMenuStrip1.ImageScalingSize = new System.Drawing.Size(24, 24);
204 | this.contextMenuStrip1.Items.AddRange(new System.Windows.Forms.ToolStripItem[] {
205 | this.新建文件夹ToolStripMenuItem,
206 | this.新建文件ToolStripMenuItem});
207 | this.contextMenuStrip1.Name = "contextMenuStrip1";
208 | this.contextMenuStrip1.Size = new System.Drawing.Size(171, 60);
209 | //
210 | // 新建文件夹ToolStripMenuItem
211 | //
212 | this.新建文件夹ToolStripMenuItem.Name = "新建文件夹ToolStripMenuItem";
213 | this.新建文件夹ToolStripMenuItem.Size = new System.Drawing.Size(170, 28);
214 | this.新建文件夹ToolStripMenuItem.Text = "新建文件夹";
215 | this.新建文件夹ToolStripMenuItem.Click += new System.EventHandler(this.新建文件夹ToolStripMenuItem_Click);
216 | //
217 | // 新建文件ToolStripMenuItem
218 | //
219 | this.新建文件ToolStripMenuItem.Name = "新建文件ToolStripMenuItem";
220 | this.新建文件ToolStripMenuItem.Size = new System.Drawing.Size(170, 28);
221 | this.新建文件ToolStripMenuItem.Text = "新建文件";
222 | this.新建文件ToolStripMenuItem.Click += new System.EventHandler(this.新建文件ToolStripMenuItem_Click);
223 | //
224 | // buttonBack
225 | //
226 | this.buttonBack.BackColor = System.Drawing.SystemColors.GradientInactiveCaption;
227 | this.buttonBack.BackgroundImageLayout = System.Windows.Forms.ImageLayout.None;
228 | this.buttonBack.Location = new System.Drawing.Point(833, 12);
229 | this.buttonBack.Margin = new System.Windows.Forms.Padding(4);
230 | this.buttonBack.Name = "buttonBack";
231 | this.buttonBack.Size = new System.Drawing.Size(160, 32);
232 | this.buttonBack.TabIndex = 24;
233 | this.buttonBack.Text = "返回上级目录";
234 | this.buttonBack.UseVisualStyleBackColor = false;
235 | this.buttonBack.Click += new System.EventHandler(this.buttonBack_Click);
236 | //
237 | // buttonDelete
238 | //
239 | this.buttonDelete.BackColor = System.Drawing.SystemColors.GradientInactiveCaption;
240 | this.buttonDelete.Location = new System.Drawing.Point(1078, 88);
241 | this.buttonDelete.Margin = new System.Windows.Forms.Padding(4);
242 | this.buttonDelete.Name = "buttonDelete";
243 | this.buttonDelete.Size = new System.Drawing.Size(177, 34);
244 | this.buttonDelete.TabIndex = 25;
245 | this.buttonDelete.Text = "格式化";
246 | this.buttonDelete.UseVisualStyleBackColor = false;
247 | this.buttonDelete.Click += new System.EventHandler(this.buttonDelete_Click);
248 | //
249 | // groupBox8
250 | //
251 | this.groupBox8.BackColor = System.Drawing.SystemColors.ActiveBorder;
252 | this.groupBox8.Location = new System.Drawing.Point(1059, 0);
253 | this.groupBox8.Margin = new System.Windows.Forms.Padding(4);
254 | this.groupBox8.Name = "groupBox8";
255 | this.groupBox8.Padding = new System.Windows.Forms.Padding(4);
256 | this.groupBox8.Size = new System.Drawing.Size(2, 588);
257 | this.groupBox8.TabIndex = 26;
258 | this.groupBox8.TabStop = false;
259 | this.groupBox8.Text = "groupBox8";
260 | //
261 | // buttonCreateFolder
262 | //
263 | this.buttonCreateFolder.BackColor = System.Drawing.SystemColors.GradientInactiveCaption;
264 | this.buttonCreateFolder.Location = new System.Drawing.Point(1078, 282);
265 | this.buttonCreateFolder.Margin = new System.Windows.Forms.Padding(4);
266 | this.buttonCreateFolder.Name = "buttonCreateFolder";
267 | this.buttonCreateFolder.Size = new System.Drawing.Size(177, 34);
268 | this.buttonCreateFolder.TabIndex = 27;
269 | this.buttonCreateFolder.Text = "新建文件夹";
270 | this.buttonCreateFolder.UseVisualStyleBackColor = false;
271 | this.buttonCreateFolder.Click += new System.EventHandler(this.buttonCreateFolder_Click);
272 | //
273 | // buttonCreateFile
274 | //
275 | this.buttonCreateFile.BackColor = System.Drawing.SystemColors.GradientInactiveCaption;
276 | this.buttonCreateFile.Location = new System.Drawing.Point(1078, 338);
277 | this.buttonCreateFile.Margin = new System.Windows.Forms.Padding(4);
278 | this.buttonCreateFile.Name = "buttonCreateFile";
279 | this.buttonCreateFile.Size = new System.Drawing.Size(177, 34);
280 | this.buttonCreateFile.TabIndex = 28;
281 | this.buttonCreateFile.Text = "新建文本文件";
282 | this.buttonCreateFile.UseVisualStyleBackColor = false;
283 | this.buttonCreateFile.Click += new System.EventHandler(this.buttonCreateFile_Click);
284 | //
285 | // labelBlockSize
286 | //
287 | this.labelBlockSize.AutoSize = true;
288 | this.labelBlockSize.Location = new System.Drawing.Point(1084, 486);
289 | this.labelBlockSize.Margin = new System.Windows.Forms.Padding(4, 0, 4, 0);
290 | this.labelBlockSize.Name = "labelBlockSize";
291 | this.labelBlockSize.Size = new System.Drawing.Size(62, 18);
292 | this.labelBlockSize.TabIndex = 32;
293 | this.labelBlockSize.Text = "label1";
294 | //
295 | // labelDiskSize
296 | //
297 | this.labelDiskSize.AutoSize = true;
298 | this.labelDiskSize.Location = new System.Drawing.Point(1084, 440);
299 | this.labelDiskSize.Margin = new System.Windows.Forms.Padding(4, 0, 4, 0);
300 | this.labelDiskSize.Name = "labelDiskSize";
301 | this.labelDiskSize.Size = new System.Drawing.Size(62, 18);
302 | this.labelDiskSize.TabIndex = 34;
303 | this.labelDiskSize.Text = "label1";
304 | //
305 | // fileWindow
306 | //
307 | this.fileWindow.BackColor = System.Drawing.SystemColors.Control;
308 | this.fileWindow.BackgroundImageLayout = System.Windows.Forms.ImageLayout.None;
309 | this.fileWindow.ContextMenuStrip = this.contextMenuStrip1;
310 | this.fileWindow.Location = new System.Drawing.Point(210, 88);
311 | this.fileWindow.Margin = new System.Windows.Forms.Padding(6);
312 | this.fileWindow.Name = "fileWindow";
313 | this.fileWindow.Size = new System.Drawing.Size(850, 500);
314 | this.fileWindow.TabIndex = 23;
315 | this.fileWindow.Load += new System.EventHandler(this.fileWindow_Load);
316 | //
317 | // groupBox9
318 | //
319 | this.groupBox9.BackColor = System.Drawing.SystemColors.ActiveBorder;
320 | this.groupBox9.Location = new System.Drawing.Point(207, 0);
321 | this.groupBox9.Margin = new System.Windows.Forms.Padding(4);
322 | this.groupBox9.Name = "groupBox9";
323 | this.groupBox9.Padding = new System.Windows.Forms.Padding(4);
324 | this.groupBox9.Size = new System.Drawing.Size(2, 588);
325 | this.groupBox9.TabIndex = 35;
326 | this.groupBox9.TabStop = false;
327 | this.groupBox9.Text = "groupBox9";
328 | //
329 | // treeView
330 | //
331 | this.treeView.ImageIndex = 0;
332 | this.treeView.ImageList = this.imageList;
333 | this.treeView.Location = new System.Drawing.Point(0, 0);
334 | this.treeView.Margin = new System.Windows.Forms.Padding(4);
335 | this.treeView.Name = "treeView";
336 | this.treeView.SelectedImageIndex = 0;
337 | this.treeView.Size = new System.Drawing.Size(205, 586);
338 | this.treeView.TabIndex = 36;
339 | this.treeView.MouseDoubleClick += new System.Windows.Forms.MouseEventHandler(this.treeView_MouseDoubleClick);
340 | //
341 | // imageList
342 | //
343 | this.imageList.ImageStream = ((System.Windows.Forms.ImageListStreamer)(resources.GetObject("imageList.ImageStream")));
344 | this.imageList.TransparentColor = System.Drawing.Color.Transparent;
345 | this.imageList.Images.SetKeyName(0, "file18.png");
346 | this.imageList.Images.SetKeyName(1, "folder18.png");
347 | //
348 | // label1
349 | //
350 | this.label1.AutoSize = true;
351 | this.label1.Font = new System.Drawing.Font("宋体", 9F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(134)));
352 | this.label1.Location = new System.Drawing.Point(229, 19);
353 | this.label1.Margin = new System.Windows.Forms.Padding(4, 0, 4, 0);
354 | this.label1.Name = "label1";
355 | this.label1.Size = new System.Drawing.Size(84, 18);
356 | this.label1.TabIndex = 37;
357 | this.label1.Text = "当前路径";
358 | this.label1.Click += new System.EventHandler(this.label1_Click);
359 | //
360 | // MainForm
361 | //
362 | this.AutoScaleDimensions = new System.Drawing.SizeF(9F, 18F);
363 | this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
364 | this.ClientSize = new System.Drawing.Size(1270, 582);
365 | this.Controls.Add(this.label1);
366 | this.Controls.Add(this.treeView);
367 | this.Controls.Add(this.groupBox9);
368 | this.Controls.Add(this.labelDiskSize);
369 | this.Controls.Add(this.labelBlockSize);
370 | this.Controls.Add(this.buttonCreateFile);
371 | this.Controls.Add(this.buttonCreateFolder);
372 | this.Controls.Add(this.groupBox8);
373 | this.Controls.Add(this.buttonDelete);
374 | this.Controls.Add(this.buttonBack);
375 | this.Controls.Add(this.fileWindow);
376 | this.Controls.Add(this.groupBox6);
377 | this.Controls.Add(this.groupBox5);
378 | this.Controls.Add(this.groupBox4);
379 | this.Controls.Add(this.groupBox2);
380 | this.Controls.Add(this.fileSize);
381 | this.Controls.Add(this.fileType);
382 | this.Controls.Add(this.modifyTime);
383 | this.Controls.Add(this.fileName);
384 | this.Controls.Add(this.groupBox1);
385 | this.Controls.Add(this.textBoxSearch);
386 | this.Icon = ((System.Drawing.Icon)(resources.GetObject("$this.Icon")));
387 | this.Margin = new System.Windows.Forms.Padding(4);
388 | this.MaximizeBox = false;
389 | this.Name = "MainForm";
390 | this.StartPosition = System.Windows.Forms.FormStartPosition.CenterScreen;
391 | this.Text = "FileManageSystem";
392 | this.Load += new System.EventHandler(this.Form1_Load);
393 | this.groupBox1.ResumeLayout(false);
394 | this.groupBox6.ResumeLayout(false);
395 | this.contextMenuStrip1.ResumeLayout(false);
396 | this.ResumeLayout(false);
397 | this.PerformLayout();
398 |
399 | }
400 |
401 | #endregion
402 | private System.Windows.Forms.GroupBox groupBox5;
403 | private System.Windows.Forms.GroupBox groupBox4;
404 | private System.Windows.Forms.GroupBox groupBox2;
405 | private System.Windows.Forms.Label fileSize;
406 | private System.Windows.Forms.Label fileType;
407 | private System.Windows.Forms.Label modifyTime;
408 | private System.Windows.Forms.Label fileName;
409 | private System.Windows.Forms.GroupBox groupBox1;
410 | private System.Windows.Forms.GroupBox groupBox3;
411 | private System.Windows.Forms.TextBox textBoxSearch;
412 | private System.Windows.Forms.GroupBox groupBox6;
413 | private System.Windows.Forms.GroupBox groupBox7;
414 | private MyControl.UserControl1 fileWindow;
415 | private System.Windows.Forms.ContextMenuStrip contextMenuStrip1;
416 | private System.Windows.Forms.ToolStripMenuItem 新建文件夹ToolStripMenuItem;
417 | private System.Windows.Forms.ToolStripMenuItem 新建文件ToolStripMenuItem;
418 | private System.Windows.Forms.Button buttonBack;
419 | private System.Windows.Forms.Button buttonDelete;
420 | private System.Windows.Forms.GroupBox groupBox8;
421 | private System.Windows.Forms.Button buttonCreateFolder;
422 | private System.Windows.Forms.Button buttonCreateFile;
423 | private System.Windows.Forms.Label labelBlockSize;
424 | private System.Windows.Forms.Label labelDiskSize;
425 | private System.Windows.Forms.GroupBox groupBox9;
426 | private System.Windows.Forms.TreeView treeView;
427 | private System.Windows.Forms.ImageList imageList;
428 | private System.Windows.Forms.Label label1;
429 | }
430 | }
431 |
432 |
--------------------------------------------------------------------------------
/文件管理_文件管理模拟系统/src/Form/MainForm/MainForm.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.ComponentModel;
4 | using System.Data;
5 | using System.Drawing;
6 | using System.Linq;
7 | using System.Text;
8 | using System.Threading.Tasks;
9 | using System.Windows.Forms;
10 | using Microsoft.VisualBasic;
11 | using System.IO;
12 | using System.Xml;
13 | using File_Management_System;
14 |
15 | namespace FileManageSystem
16 | {
17 | public partial class MainForm : Form
18 | {
19 | public Category category = new Category(); //创建目录
20 | public Category.Node rootNode = new Category.Node(); //目录的根节点
21 | public Category.Node currentRoot = new Category.Node(); //当前根节点为root
22 | public VirtualDisk MyDisk = new VirtualDisk(1000, 2); //申请内存空间
23 |
24 | public string nowPath;
25 | public string change;
26 |
27 | public MainForm()
28 | {
29 | this.StartPosition = FormStartPosition.CenterScreen;
30 | FCB root = new FCB("root", FCB.FOLDER, "", 1);
31 | rootNode = new Category.Node(root);
32 | currentRoot = rootNode;
33 | category.root = rootNode;
34 |
35 | /*恢复文件管理系统*/
36 | readFormDisk(); //读取目录信息文件
37 | readBitMap(); //读取位图文件
38 | readMyDisk(); //读取虚拟磁盘文件
39 |
40 | InitializeComponent();
41 | }
42 |
43 | //判断控件内按钮点击
44 | public void MyControlButtonClick(object sender, EventArgs e)
45 | {
46 | if (sender.GetType().ToString() == "System.Windows.Forms.Button")
47 | {
48 | Button bt = (Button)sender; //当前点击的按钮
49 | if (bt.Tag.ToString() == "0") //文件
50 | {
51 | NoteForm file = new NoteForm(bt.Text, this); //弹出记事本窗口
52 | file.Show();
53 | }
54 | else if (bt.Tag.ToString() == "1")//文件夹
55 | {
56 | currentRoot = category.search(rootNode, bt.Text, 1); //更改当前根节点
57 | nowPath = nowPath + "> " + bt.Text; //更改当前路径
58 | fileFormInit(currentRoot); //更新界面元素
59 | }
60 | }
61 | else
62 | {
63 | string filename = fileWindow.contextMenuStrip_FileChoose.SourceControl.Text;
64 | string type = fileWindow.contextMenuStrip_FileChoose.SourceControl.Tag.ToString();
65 | if (((ToolStripMenuItem)sender).Name == "打开ToolStripMenuItem")
66 | {
67 | if (type == "0") //文件
68 | {
69 | NoteForm file = new NoteForm(filename, this);
70 | file.Show();
71 | }
72 | else if (type == "1")//文件夹
73 | {
74 | currentRoot = category.search(rootNode, filename, 1);
75 | nowPath = nowPath + "> " + filename;
76 | fileFormInit(currentRoot);
77 | }
78 | }
79 | else if (((ToolStripMenuItem)sender).Name == "删除ToolStripMenuItem")
80 | {
81 | if (type == "0")
82 | {
83 | delete(filename, 0);
84 | }
85 | else if (type == "1")
86 | {
87 | delete(filename, 1);
88 | }
89 | }
90 | }
91 | }
92 |
93 |
94 | //初始化当前结点下的界面
95 | public void fileFormInit(Category.Node now)
96 | {
97 | labelDiskSize.Text = "当前磁盘大小: " + MyDisk.size.ToString() + "B";
98 | labelBlockSize.Text = "当前盘块大小: " + MyDisk.blockSize.ToString() + "B";
99 |
100 | if (now.fcb.fileName == "root") //当前目录为root时禁用返回上一层按钮
101 | buttonBack.Enabled = false;
102 | else
103 | buttonBack.Enabled = true;
104 |
105 | textBoxSearch.Text = nowPath; //更新路径
106 |
107 | string name = now.fcb.fileName;
108 | //窗体初始化
109 | this.fileWindow.Init();
110 |
111 | //按照左孩子-右兄弟树的结构, 依次显示该目录下的文件夹/文件
112 | if (now.firstChild == null)
113 | return;
114 | Category.Node temp = new Category.Node();
115 | temp = now.firstChild;
116 | fileWindow.showFiles(temp.fcb.fileName, temp.fcb.lastModify, temp.fcb.type, temp.fcb.size);
117 | temp = temp.nextBrother;
118 | while (temp != null)
119 | {
120 | FCB current = temp.fcb;
121 | fileWindow.showFiles(temp.fcb.fileName, temp.fcb.lastModify, temp.fcb.type, temp.fcb.size);
122 | temp = temp.nextBrother;
123 | }
124 | }
125 | //界面加载
126 | private void Form1_Load(object sender, EventArgs e)
127 | {
128 | //帮助界面
129 | HelpForm helpForm = new HelpForm();
130 | helpForm.StartPosition = FormStartPosition.CenterScreen;
131 | helpForm.Show(this);
132 |
133 | //左侧的目录树
134 | fileFormInit(rootNode);
135 | createTreeView(rootNode.firstChild);
136 | fileWindow.btnClick += new EventHandler(MyControlButtonClick);
137 | }
138 |
139 | //新建文件
140 | public void createFile()
141 | {
142 | string str = Interaction.InputBox("请输入文件的名称", "字符串", "", 100, 100);
143 | if (str != "")
144 | {
145 | if (category.noSameName(str, currentRoot, FCB.TXTFILE))
146 | {
147 | string time = DateTime.Now.ToLocalTime().ToString(); //获取时间信息
148 | if (fileWindow.showFiles(str, time, FCB.TXTFILE, 0))
149 | category.createFile(currentRoot.fcb.fileName, new FCB(str, FCB.TXTFILE, time, 0)); //文件加入到目录中
150 | }
151 | else
152 | {
153 | MessageBox.Show("已存在名为" + str + ".txt的文件,创建失败!");
154 | }
155 | }
156 | //目录树更新
157 | treeView.Nodes.Clear();
158 | createTreeView(rootNode.firstChild);
159 | }
160 | private void 新建文件ToolStripMenuItem_Click(object sender, EventArgs e)
161 | {
162 | createFile();
163 | }
164 | private void buttonCreateFile_Click(object sender, EventArgs e)
165 | {
166 | createFile();
167 | }
168 |
169 | //新建文件夹
170 | public void createFolder()
171 | {
172 | string str = Interaction.InputBox("请输入文件夹的名称", "字符串", "", 100, 100);
173 | if (str != "")
174 | {
175 | if(str==currentRoot.fcb.fileName) //如果跟上级根目录重名, 添加一个_做标识
176 | {
177 | str = "_" + str;
178 | }
179 | if (category.noSameName(str, currentRoot, FCB.FOLDER))
180 | {
181 | string time = DateTime.Now.ToLocalTime().ToString();
182 | if (fileWindow.showFiles(str, time, FCB.FOLDER, 0))
183 | category.createFile(currentRoot.fcb.fileName, new FCB(str, FCB.FOLDER, time, 0)); //文件夹加入到目录中
184 | }
185 | else
186 | {
187 | MessageBox.Show("已存在名为" + str + "的文件夹,创建失败!");
188 | }
189 | }
190 | //目录树更新
191 | treeView.Nodes.Clear();
192 | createTreeView(rootNode.firstChild);
193 | }
194 | private void 新建文件夹ToolStripMenuItem_Click(object sender, EventArgs e)
195 | {
196 | createFolder();
197 | }
198 | private void buttonCreateFolder_Click(object sender, EventArgs e)
199 | {
200 | createFolder();
201 | }
202 |
203 | //删除内容
204 | public void delete(string name, int type)
205 | {
206 | if (type == FCB.TXTFILE) //删除文件
207 | {
208 | FCB deleteFCB = category.search(rootNode, name, type).fcb;
209 | category.deleteFile(name);
210 | category.delete(category.search(rootNode, name, FCB.TXTFILE
211 | ));
212 | MyDisk.deleteFileContent(deleteFCB.start, deleteFCB.size);
213 | fileFormInit(currentRoot);
214 | }
215 | else //删除文件夹
216 | {
217 | category.deleteFolder(name);
218 | fileFormInit(currentRoot);
219 | }
220 | //目录树更新
221 | treeView.Nodes.Clear();
222 | createTreeView(rootNode.firstChild);
223 | }
224 |
225 | //返回上一级目录
226 | private void buttonBack_Click(object sender, EventArgs e)
227 | {
228 | nowPath = nowPath.Replace("> " + currentRoot.fcb.fileName, "");
229 | currentRoot = currentRoot.parent;
230 | fileFormInit(currentRoot);
231 | }
232 |
233 | //格式化
234 | private void buttonDelete_Click(object sender, EventArgs e)
235 | {
236 | DialogResult result = MessageBox.Show("确定清空磁盘?", "提示信息", MessageBoxButtons.OKCancel, MessageBoxIcon.Information);
237 | if (result == DialogResult.OK)
238 | {
239 | category.freeCategory(category.root);
240 | for (int i = 0; i < MyDisk.blockSize; i++)
241 | {
242 | MyDisk.memory[i] = "";
243 | MyDisk.bitMap[i] = -1;
244 | MyDisk.remain = MyDisk.blockNum;
245 | }
246 | MessageBox.Show("磁盘已清空。");
247 | fileFormInit(rootNode);
248 |
249 | nowPath = "";
250 | textBoxSearch.Text = "";
251 | treeView.Nodes.Clear();
252 |
253 | updateLog(); //清空所有日志文件
254 | }
255 |
256 | }
257 |
258 |
259 | //创建目录树
260 | public void createTreeView(Category.Node pNode)
261 | {
262 | if (pNode == null) //目录为空, 不需要创建目录树
263 | return;
264 |
265 | /*文件夹和文本文件分别创建目录树结点*/
266 | TreeNode tn = new TreeNode();
267 | if (pNode.fcb.type == FCB.FOLDER)
268 | {
269 | tn.Name = pNode.fcb.fileName;
270 | tn.Text = pNode.fcb.fileName;
271 | tn.Tag = 1;
272 | tn.ImageIndex = 1;
273 | tn.SelectedImageIndex = 1;
274 | }
275 | else if (pNode.fcb.type == FCB.TXTFILE)
276 | {
277 | tn.Name = pNode.fcb.fileName + ".txt";
278 | tn.Text = pNode.fcb.fileName + ".txt";
279 | tn.Tag = 0;
280 | tn.ImageIndex = 0;
281 | tn.SelectedImageIndex = 0;
282 | }
283 |
284 | /*只需按照一个左孩子一个右兄弟建立目录树*/
285 | if (pNode.parent == rootNode)
286 | {
287 | treeView.Nodes.Add(tn);
288 | }
289 | else
290 | {
291 | CallAddNode(treeView, pNode.parent.fcb.fileName, tn);
292 | }
293 | createTreeView(pNode.firstChild);
294 | createTreeView(pNode.nextBrother);
295 | }
296 | //双击目录树结点打开文件或者文件夹
297 | private void treeView_MouseDoubleClick(object sender, MouseEventArgs e)
298 | {
299 | TreeNode tn = treeView.SelectedNode;
300 |
301 | if (tn.Tag.ToString() == "1") //打开文件夹
302 | {
303 | Stack s = new Stack();
304 | s.Push(tn);
305 | currentRoot = category.search(rootNode, tn.Text, FCB.FOLDER);
306 |
307 | //更新路径
308 | nowPath = "";
309 | while (tn.Parent != null)
310 | {
311 | s.Push(tn.Parent);
312 | tn = tn.Parent;
313 | }
314 | nowPath = "";
315 | while (s.Count() != 0)
316 | {
317 | nowPath += "> " + s.Pop().Text;
318 | }
319 | textBoxSearch.Text = nowPath;
320 |
321 | //刷新新目录下的界面
322 | fileFormInit(currentRoot);
323 | }
324 | else if (tn.Tag.ToString() == "0") //打开文件
325 | {
326 | NoteForm file = new NoteForm(tn.Text.Replace(".txt", ""), this);
327 | file.Show();
328 | }
329 | }
330 | //递归查找往目录树中加入结点
331 | public TreeNode AddNode(TreeNode tnParent, string tnStr, TreeNode newTn)
332 | {
333 | if (tnParent == null)
334 | return null;
335 | if (tnParent.Name == tnStr)
336 | {
337 | tnParent.Nodes.Add(newTn);
338 | }
339 |
340 | TreeNode tnRet = null;
341 | foreach (TreeNode tn in tnParent.Nodes)
342 | {
343 | tnRet = AddNode(tn, tnStr, newTn);
344 | if (tnRet != null)
345 | {
346 | tnRet.Nodes.Add(newTn);
347 | break;
348 | }
349 | }
350 | return tnRet;
351 | }
352 | public TreeNode CallAddNode(TreeView tree, string tnStr, TreeNode newTn)
353 | {
354 | foreach (TreeNode n in tree.Nodes)
355 | {
356 | TreeNode temp = AddNode(n, tnStr, newTn);
357 | if (temp != null)
358 | return temp;
359 | }
360 | return null;
361 | }
362 |
363 |
364 | /*
365 | * CategoryInfo.txt中信息格式
366 | *
367 | * 当前目录下的根节点
368 | * 文件名称
369 | * 文件类型
370 | * 上次修改时间
371 | * 文件大小
372 | * 文件起始位置
373 | * #分隔符
374 | *
375 | */
376 | /*目录信息*/
377 | public void readFormDisk()
378 | {
379 | //把本地保存的上次的结点信息写回来
380 | string path = Application.StartupPath + "\\CategoryInfo.txt";
381 | if (File.Exists(path))
382 | {
383 | StreamReader reader = new StreamReader(path);
384 | string parentName = "", Name = ""; //父结点名字,自己的名字
385 | string lastModify = ""; //最后修改时间
386 | int type = -1, size = 0, start = -1, infoNum = 1;
387 |
388 | //逐行读取信息
389 | string str = reader.ReadLine();
390 | while (str != null)
391 | {
392 | switch (infoNum)
393 | {
394 | case 1:
395 | parentName = str;
396 | infoNum++;
397 | break;
398 | case 2:
399 | Name = str;
400 | infoNum++;
401 | break;
402 | case 3:
403 | type = int.Parse(str);
404 | infoNum++;
405 | break;
406 | case 4:
407 | lastModify = str;
408 | infoNum++;
409 | break;
410 | case 5:
411 | size = int.Parse(str);
412 | infoNum++;
413 | break;
414 | case 6:
415 | start = int.Parse(str);
416 | infoNum++;
417 | break;
418 | case 7:
419 | infoNum = 1;
420 | FCB now = new FCB(Name, type, lastModify, size);
421 | category.createFile(parentName, now); //把文件结点的内容加到目录中
422 | break;
423 | default:
424 | break;
425 | }
426 | str = reader.ReadLine();
427 | }
428 | reader.Close();
429 | }
430 |
431 | }
432 | public void writeCategory(Category.Node pNode)
433 | {
434 | //当前结点的父结点
435 | Category.Node parentNode = category.currentRootName(rootNode, pNode.fcb.fileName, pNode.fcb.type);
436 | string InfoPath = Application.StartupPath + "\\CategoryInfo.txt";
437 | StreamWriter writer = File.AppendText(InfoPath);
438 |
439 | writer.WriteLine(parentNode.fcb.fileName); //写入父结点的名字
440 | writer.WriteLine(pNode.fcb.fileName); //写入文件的名字
441 | writer.WriteLine(pNode.fcb.type); //写入文件的类型
442 | writer.WriteLine(pNode.fcb.lastModify); //写入最后修改的时间
443 | writer.WriteLine(pNode.fcb.size); //写入文件的大小
444 | if (pNode.fcb.type == FCB.TXTFILE) //写入文件的开始位置
445 | {
446 | writer.WriteLine(pNode.fcb.start);
447 | }
448 | else if (pNode.fcb.type == FCB.FOLDER) //若为文件夹则写入-1
449 | {
450 | writer.WriteLine(-1);
451 | }
452 | writer.WriteLine("#"); //一个结点写完
453 |
454 | writer.Close();
455 | }
456 |
457 | /*位图文件*/
458 | public void readBitMap()
459 | {
460 | string path = Application.StartupPath + "\\BitMapInfo.txt";
461 | if (File.Exists(path))
462 | {
463 | StreamReader reader = new StreamReader(path);
464 | for (int i = 0; i < MyDisk.blockNum; i++)
465 | {
466 | MyDisk.bitMap[i] = int.Parse(reader.ReadLine());
467 | }
468 | reader.Close();
469 | }
470 | }
471 | public void writeBitMap()
472 | {
473 | if (File.Exists(Application.StartupPath + "\\BitMapInfo.txt"))
474 | File.Delete(Application.StartupPath + "\\BitMapInfo.txt");
475 | StreamWriter writer = new StreamWriter(Application.StartupPath + "\\BitMapInfo.txt");
476 |
477 | for (int i = 0; i < MyDisk.blockNum; i++)
478 | {
479 | writer.WriteLine(MyDisk.bitMap[i]);
480 | }
481 | writer.Close();
482 | }
483 |
484 | /*虚拟磁盘文件*/
485 | public void readMyDisk()
486 | {
487 | string path = Application.StartupPath + "\\MyDiskInfo.txt";
488 | if (File.Exists(path))
489 | {
490 | StreamReader reader = new StreamReader(path);
491 | for (int i = 0; i < MyDisk.blockNum; i++)
492 | {
493 | string str = reader.ReadLine();
494 | if (str.IndexOf("()") >= 0)
495 | MyDisk.memory[i] = str.Replace("()", "\r\n");
496 | else
497 | {
498 | if (str.IndexOf('(') >= 0)
499 | MyDisk.memory[i] = str.Replace('(', '\r');
500 | else if (str.IndexOf(')') >= 0)
501 | MyDisk.memory[i] = str.Replace(')', '\n');
502 | else if (str != "#")
503 | MyDisk.memory[i] = str;
504 | else if (str == "#")
505 | MyDisk.memory[i] = "";
506 | }
507 | }
508 | reader.Close();
509 | }
510 | }
511 | public void writeMyDisk()
512 | {
513 | if (File.Exists(Application.StartupPath + "\\MyDiskInfo.txt"))
514 | File.Delete(Application.StartupPath + "\\MyDiskInfo.txt");
515 | StreamWriter writer = new StreamWriter(Application.StartupPath + "\\MyDiskInfo.txt");
516 |
517 | for (int i = 0; i < MyDisk.blockNum; i++)
518 | {
519 | if (MyDisk.memory[i].IndexOf("\r\n") >= 0)
520 | {
521 | writer.WriteLine(MyDisk.memory[i].Replace("\r\n", "()"));
522 | }
523 | else
524 | {
525 | if (MyDisk.memory[i].IndexOf('\r') >= 0)
526 | {
527 | writer.WriteLine(MyDisk.memory[i].Replace('\r', '('));
528 | }
529 | else if (MyDisk.memory[i].IndexOf('\n') >= 0)
530 | {
531 | writer.WriteLine(MyDisk.memory[i].Replace('\n', ')'));
532 | }
533 | else if (MyDisk.memory[i] != "")
534 | writer.WriteLine(MyDisk.memory[i]);
535 | else
536 | writer.WriteLine("#");
537 | }
538 | }
539 | writer.Close();
540 | }
541 |
542 |
543 |
544 | //主窗体关闭时,把所有的内容写入到本地
545 | protected override void OnFormClosing(FormClosingEventArgs e)
546 | {
547 | updateLog();
548 | }
549 |
550 | //更新所有日志信息,将所有的内容写入到本地
551 | public void updateLog()
552 | {
553 | if (File.Exists(Application.StartupPath + "\\CategoryInfo.txt"))
554 | File.Delete(Application.StartupPath + "\\CategoryInfo.txt");
555 | Category.Node temp = new Category.Node();
556 | string path = Application.StartupPath;
557 | Queue q = new Queue();
558 | q.Enqueue(category.root);
559 |
560 | while (q.Count() != 0)
561 | {
562 | temp = q.Dequeue();
563 | temp = temp.firstChild;
564 | while (temp != null)
565 | {
566 | q.Enqueue(temp);
567 | writeCategory(temp);
568 | temp = temp.nextBrother;
569 | }
570 | }
571 |
572 | writeBitMap();
573 | writeMyDisk();
574 | }
575 |
576 | private void textBox1_TextChanged(object sender, EventArgs e)
577 | {
578 |
579 | }
580 |
581 | private void fileWindow_Load(object sender, EventArgs e)
582 | {
583 |
584 | }
585 |
586 | private void label1_Click(object sender, EventArgs e)
587 | {
588 |
589 | }
590 | }
591 |
592 | }
593 |
--------------------------------------------------------------------------------
/文件管理_文件管理模拟系统/src/Form/NoteForm/NoteForm.Designer.cs:
--------------------------------------------------------------------------------
1 | namespace FileManageSystem
2 | {
3 | partial class NoteForm
4 | {
5 | ///
6 | /// Required designer variable.
7 | ///
8 | private System.ComponentModel.IContainer components = null;
9 |
10 | ///
11 | /// Clean up any resources being used.
12 | ///
13 | /// true if managed resources should be disposed; otherwise, false.
14 | protected override void Dispose(bool disposing)
15 | {
16 | if (disposing && (components != null))
17 | {
18 | components.Dispose();
19 | }
20 | base.Dispose(disposing);
21 | }
22 |
23 | #region Windows Form Designer generated code
24 |
25 | ///
26 | /// Required method for Designer support - do not modify
27 | /// the contents of this method with the code editor.
28 | ///
29 | private void InitializeComponent()
30 | {
31 | System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(NoteForm));
32 | this.textBox1 = new System.Windows.Forms.TextBox();
33 | this.SuspendLayout();
34 | //
35 | // textBox1
36 | //
37 | this.textBox1.Location = new System.Drawing.Point(0, 0);
38 | this.textBox1.Margin = new System.Windows.Forms.Padding(4);
39 | this.textBox1.Multiline = true;
40 | this.textBox1.Name = "textBox1";
41 | this.textBox1.Size = new System.Drawing.Size(613, 470);
42 | this.textBox1.TabIndex = 0;
43 | this.textBox1.UseWaitCursor = true;
44 | this.textBox1.TextChanged += new System.EventHandler(this.textBox1_TextChanged);
45 | //
46 | // fileRW
47 | //
48 | this.AutoScaleDimensions = new System.Drawing.SizeF(9F, 18F);
49 | this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
50 | this.ClientSize = new System.Drawing.Size(614, 468);
51 | this.Controls.Add(this.textBox1);
52 | this.Icon = ((System.Drawing.Icon)(resources.GetObject("$this.Icon")));
53 | this.Margin = new System.Windows.Forms.Padding(4);
54 | this.MaximizeBox = false;
55 | this.Name = "fileRW";
56 | this.StartPosition = System.Windows.Forms.FormStartPosition.CenterScreen;
57 | this.Text = "fileRW";
58 | this.UseWaitCursor = true;
59 | this.Load += new System.EventHandler(this.NoteForm_Load);
60 | this.ResumeLayout(false);
61 | this.PerformLayout();
62 |
63 | }
64 |
65 | #endregion
66 |
67 | private System.Windows.Forms.TextBox textBox1;
68 | }
69 | }
--------------------------------------------------------------------------------
/文件管理_文件管理模拟系统/src/Form/NoteForm/NoteForm.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.ComponentModel;
4 | using System.Data;
5 | using System.Drawing;
6 | using System.Linq;
7 | using System.Text;
8 | using System.Threading.Tasks;
9 | using System.Windows.Forms;
10 |
11 | namespace FileManageSystem
12 | {
13 | public partial class NoteForm : Form
14 | {
15 | public static bool ischanged = false; //状态位 -> 用户打开记事本是否进行编辑
16 | public MainForm mainForm;
17 | public string filename;
18 |
19 | public NoteForm(string Name, MainForm parent)
20 | {
21 | mainForm = parent;
22 | filename = Name;
23 |
24 | InitializeComponent();
25 | }
26 |
27 | /*关闭记事本*/
28 | protected override void OnFormClosing(FormClosingEventArgs e)
29 | {
30 | if (ischanged == true) //如果用户更改记事本 => 弹出提示框提醒保存
31 | {
32 | DialogResult result = MessageBox.Show("是否进行保存?", "提示信息", MessageBoxButtons.OKCancel, MessageBoxIcon.Information);
33 | if (result == DialogResult.OK)
34 | {
35 | FCB nowFCB = mainForm.category.search(mainForm.category.root, filename, 0).fcb;
36 | int oldSize = nowFCB.size;
37 | int oldStart = nowFCB.start;
38 |
39 | string content = textBox1.Text.Trim();
40 | if (content != "")
41 | { MessageBox.Show("保存成功!"); }
42 |
43 | nowFCB.size = textBox1.Text.Trim().Length;
44 | nowFCB.lastModify = DateTime.Now.ToLocalTime().ToString(); //获取当前时间
45 |
46 | //在内存上给文件分配空间
47 | if (nowFCB.size>0)
48 | {
49 | if(mainForm.MyDisk.remain<=textBox1.Text.Trim().Length)
50 | {
51 | MessageBox.Show("磁盘空间不足!");
52 | }
53 | else
54 | {
55 | if(oldStart==-1) //如果该文本文件之前为空(第一次修改)
56 | {
57 | mainForm.MyDisk.giveSpace(nowFCB, textBox1.Text.Trim());
58 | }
59 | else //更新
60 | {
61 | mainForm.MyDisk.fileUpdate(oldStart, oldSize,nowFCB, textBox1.Text.Trim());
62 | }
63 | }
64 |
65 |
66 | }
67 | mainForm.fileFormInit(mainForm.currentRoot);
68 | }
69 | else
70 | {
71 | e.Cancel = false; //不保存直接退出
72 | }
73 | }
74 | else
75 | e.Cancel = false; //用户未编辑直接退出
76 | }
77 |
78 | private void textBox1_TextChanged(object sender, EventArgs e)
79 | {
80 | ischanged = true;
81 | }
82 |
83 | private void NoteForm_Load(object sender, EventArgs e)
84 | {
85 | this.Text = filename + ".txt";
86 | FCB nowFCB = mainForm.category.search(mainForm.category.root, filename, 0).fcb;
87 | if (mainForm.MyDisk.getFileContent(nowFCB) != "")
88 | {
89 | textBox1.AppendText(mainForm.MyDisk.getFileContent(nowFCB)); //读取保存的文本文件信息
90 | }
91 | ischanged = false;
92 | }
93 | }
94 | }
95 |
--------------------------------------------------------------------------------
/文件管理_文件管理模拟系统/src/Program.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Threading.Tasks;
5 | using System.Windows.Forms;
6 |
7 | namespace FileManageSystem
8 | {
9 | static class Program
10 | {
11 | ///
12 | /// 应用程序的主入口点。
13 | ///
14 | [STAThread]
15 | static void Main()
16 | {
17 | Application.EnableVisualStyles();
18 | Application.SetCompatibleTextRenderingDefault(false);
19 | Application.Run(new MainForm());
20 | }
21 | }
22 | }
23 |
--------------------------------------------------------------------------------
/文件管理_文件管理模拟系统/src/VirtualDisk.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Text;
5 | using System.Threading.Tasks;
6 |
7 | namespace FileManageSystem
8 | {
9 | public class VirtualDisk
10 | {
11 | public const int EMPTY = -1; //当前块为空
12 | public const int END = -2; //结束标识
13 |
14 | public int size; //磁盘容量
15 | public int remain; //磁盘剩余空间
16 | public int blockSize; //块大小
17 | public int blockNum; //磁盘块数
18 | public string[] memory = new string[] { }; //内存空间
19 | public int[] bitMap = new int[] { }; //位图表
20 |
21 |
22 | public VirtualDisk(int size, int blocksize)
23 | {
24 | this.size = size;
25 | this.blockSize = blocksize;
26 | this.blockNum = size / blockSize;
27 | this.remain = blockNum;
28 |
29 | this.memory = new string[blockNum];
30 | this.bitMap = new int[blockNum];
31 | for (int i = 0; i < blockNum; i++)
32 | {
33 | this.bitMap[i] = EMPTY; //初始化位图表为全部可用
34 | this.memory[i] = ""; //初始化内存内容为空
35 | }
36 |
37 | }
38 |
39 | /*给文件分配空间并添加内容*/
40 | public bool giveSpace(FCB fcb, string content)
41 | {
42 | int blocks = getBlockSize(fcb.size);
43 |
44 | if (blocks <= remain)
45 | {
46 | /*找到该文件开始存放的位置*/
47 | int start = 0;
48 | for (int i = 0; i < blockNum; i++)
49 | {
50 | if (bitMap[i] == EMPTY)
51 | {
52 | remain--;
53 | start = i;
54 | fcb.start = i;
55 | memory[i] = content.Substring(0, blockSize);
56 |
57 | break;
58 | }
59 | }
60 |
61 | /*从该位置往后开始存放内容*/
62 | for (int j = 1, i = start + 1; j < blocks && i < blockNum; i++)
63 | {
64 | if (bitMap[i] == EMPTY)
65 | {
66 | remain--;
67 |
68 | bitMap[start] = i; //以链接的方式存储每位数据
69 | start = i;
70 |
71 | if (blocks != 1)
72 | {
73 | if (j != blocks - 1)
74 | {
75 | memory[i] = content.Substring(j * blockSize, blockSize);
76 | }
77 | else
78 | {
79 | bitMap[i] = END; //文件尾
80 | if (fcb.size % blockSize != 0)
81 | {
82 | memory[i] = content.Substring(j * blockSize, content.Length - j * blockSize);
83 | }
84 | else
85 | {
86 | memory[i] = content.Substring(j * blockSize, blockSize);
87 | }
88 | }
89 |
90 | }
91 | else
92 | { memory[i] = content; }
93 |
94 | j++; //找到一个位置
95 | }
96 | }
97 | return true;
98 | }
99 | else
100 | { return false; }
101 |
102 | }
103 |
104 | /*读取文件内容*/
105 | public string getFileContent(FCB fcb)
106 | {
107 | if (fcb.start == EMPTY)
108 | { return ""; }
109 | else
110 | {
111 | string content = "";
112 | int start = fcb.start;
113 | int blocks = getBlockSize(fcb.size);
114 |
115 | int count = 0, i = start;
116 | while(i < blockNum)
117 | {
118 | if (count == blocks)
119 | {
120 | break;
121 | }
122 | else
123 | {
124 | content += memory[i]; //内容拼接内存的一个单元的数据
125 | i = bitMap[i]; //跳转到位图指向的下一个存储单元
126 | count++;
127 | }
128 | }
129 |
130 | return content;
131 | }
132 | }
133 |
134 | /*删除文件内容*/
135 | public void deleteFileContent(int start,int size)
136 | {
137 | int blocks = getBlockSize(size);
138 |
139 | int count = 0, i = start;
140 | while(i < blockNum)
141 | {
142 | if (count == blocks)
143 | {
144 | break;
145 | }
146 | else
147 | {
148 | memory[i] = ""; //逐内存单元的清空
149 | remain++;
150 |
151 | int next = bitMap[i]; //先记录即将跳转的位置
152 | bitMap[i] = EMPTY; //清空该位
153 | i = next;
154 |
155 | count++;
156 | }
157 | }
158 | }
159 |
160 | /*更新文件内容*/
161 | public void fileUpdate(int oldStart,int oldSize, FCB newFcb, string newContent)
162 | {
163 | deleteFileContent(oldStart, oldSize); //删除原内容
164 | giveSpace(newFcb, newContent); //开辟新的块并添加内容
165 | }
166 |
167 |
168 | /*获取所占块数*/
169 | private int getBlockSize(int size)
170 | {
171 | return size / blockSize + (size % blockSize != 0 ? 1 : 0);
172 | }
173 | }
174 | }
175 |
--------------------------------------------------------------------------------
/文件管理_文件管理模拟系统/工程文件整体(防丢失).rar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/doubleZ0108/Operating-System/f00305ef02f4c4b7a92252947dcd559e7602c434/文件管理_文件管理模拟系统/工程文件整体(防丢失).rar
--------------------------------------------------------------------------------
/文件管理_文件管理模拟系统/文件管理系统_设计方案报告.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/doubleZ0108/Operating-System/f00305ef02f4c4b7a92252947dcd559e7602c434/文件管理_文件管理模拟系统/文件管理系统_设计方案报告.pdf
--------------------------------------------------------------------------------
/进程管理_电梯调度/README.md:
--------------------------------------------------------------------------------
1 | # 进程管理 - 电梯调度
2 |
3 | ###### 操作系统第一次课程作业 - 电梯调度
4 |
5 | ## 目录
6 |
7 | - [开发环境](#开发环境)
8 | - [操作说明](#操作说明)
9 | - [项目结构](#项目结构)
10 | - [作者](#作者)
11 |
12 |
13 |
14 | ## 开发环境
15 |
16 | - **开发环境:** Windows 10
17 | - **开发软件:**
18 | 1. **PyCharm** *2019.1.1.PC-191.6605.12*
19 | 2. **Qt Designer** *v5.11.2.0*
20 | - **开发语言:** python3
21 | - **主要引用块内容:**
22 | 1. PyQt5 (QTimer, QtCore, QtGui, QtWidgets)
23 | 2. pyqt5-tools
24 | 3. threading
25 |
26 |
27 |
28 | ## 操作说明
29 |
30 | - 双击运行`myElevator.exe`, 进入电梯模拟系统如下图
31 |
32 | 
33 |
34 | - 点击每部电梯的**功能键**(*开/关键*, *报警器*, *楼层按钮*), 进行**单部电梯内命令处理**模拟
35 |
36 | 
37 |
38 | - 在上方**下拉框**中选择所在楼层, 并**点击上/下按钮**, 进行**多部电梯外命令处理**模拟
39 |
40 | 
41 |
42 | - **下拉框**中选择所在楼层, 并点击未被禁用**电梯的上/下行开关****(互联结)*, 进行**多部电梯外命令处理**模拟
43 |
44 | 
45 |
46 |
47 |
48 | ## 项目结构
49 |
50 | ```
51 | │ myElevator.exe
52 | │ README.md
53 | │ 电梯调度_设计方案报告.md
54 | │
55 | ├─Resources
56 | │ ├─Button
57 | │ │ doordown.png
58 | │ │ doordown_hover.png
59 | │ │ doordown_pressed.png
60 | │ │ doorup.png
61 | │ │ doorup_hover.png
62 | │ │ doorup_pressed.png
63 | │ │ down.png
64 | │ │ down_hover.png
65 | │ │ down_pressed.png
66 | │ │ state.png
67 | │ │ state_down.png
68 | │ │ state_up.png
69 | │ │ up.png
70 | │ │ up_hover.png
71 | │ │ up_pressed.png
72 | │ │
73 | │ ├─Figure
74 | │ │ people.png
75 | │ │
76 | │ └─Icon
77 | │ elevator.ico
78 | │ icon.png
79 | │
80 | └─Src
81 | dispatch.py
82 | myElevator.py
83 | myElevatorInterface.py
84 | ```
85 |
86 |
87 |
88 |
89 | #### 作者
90 |
91 | **学号** 1754060
92 |
93 | **姓名** 张喆
94 |
95 | **指导老师** 王冬青老师
96 |
97 | **上课时间** 周三/周五 上午一二节
98 |
99 | **联系方式** *email:* doubleZ0108@gmail.com
100 |
--------------------------------------------------------------------------------
/进程管理_电梯调度/Resources/Button/doordown.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/doubleZ0108/Operating-System/f00305ef02f4c4b7a92252947dcd559e7602c434/进程管理_电梯调度/Resources/Button/doordown.png
--------------------------------------------------------------------------------
/进程管理_电梯调度/Resources/Button/doordown_hover.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/doubleZ0108/Operating-System/f00305ef02f4c4b7a92252947dcd559e7602c434/进程管理_电梯调度/Resources/Button/doordown_hover.png
--------------------------------------------------------------------------------
/进程管理_电梯调度/Resources/Button/doordown_pressed.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/doubleZ0108/Operating-System/f00305ef02f4c4b7a92252947dcd559e7602c434/进程管理_电梯调度/Resources/Button/doordown_pressed.png
--------------------------------------------------------------------------------
/进程管理_电梯调度/Resources/Button/doorup.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/doubleZ0108/Operating-System/f00305ef02f4c4b7a92252947dcd559e7602c434/进程管理_电梯调度/Resources/Button/doorup.png
--------------------------------------------------------------------------------
/进程管理_电梯调度/Resources/Button/doorup_hover.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/doubleZ0108/Operating-System/f00305ef02f4c4b7a92252947dcd559e7602c434/进程管理_电梯调度/Resources/Button/doorup_hover.png
--------------------------------------------------------------------------------
/进程管理_电梯调度/Resources/Button/doorup_pressed.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/doubleZ0108/Operating-System/f00305ef02f4c4b7a92252947dcd559e7602c434/进程管理_电梯调度/Resources/Button/doorup_pressed.png
--------------------------------------------------------------------------------
/进程管理_电梯调度/Resources/Button/down.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/doubleZ0108/Operating-System/f00305ef02f4c4b7a92252947dcd559e7602c434/进程管理_电梯调度/Resources/Button/down.png
--------------------------------------------------------------------------------
/进程管理_电梯调度/Resources/Button/down_hover.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/doubleZ0108/Operating-System/f00305ef02f4c4b7a92252947dcd559e7602c434/进程管理_电梯调度/Resources/Button/down_hover.png
--------------------------------------------------------------------------------
/进程管理_电梯调度/Resources/Button/down_pressed.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/doubleZ0108/Operating-System/f00305ef02f4c4b7a92252947dcd559e7602c434/进程管理_电梯调度/Resources/Button/down_pressed.png
--------------------------------------------------------------------------------
/进程管理_电梯调度/Resources/Button/state.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/doubleZ0108/Operating-System/f00305ef02f4c4b7a92252947dcd559e7602c434/进程管理_电梯调度/Resources/Button/state.png
--------------------------------------------------------------------------------
/进程管理_电梯调度/Resources/Button/state_down.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/doubleZ0108/Operating-System/f00305ef02f4c4b7a92252947dcd559e7602c434/进程管理_电梯调度/Resources/Button/state_down.png
--------------------------------------------------------------------------------
/进程管理_电梯调度/Resources/Button/state_up.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/doubleZ0108/Operating-System/f00305ef02f4c4b7a92252947dcd559e7602c434/进程管理_电梯调度/Resources/Button/state_up.png
--------------------------------------------------------------------------------
/进程管理_电梯调度/Resources/Button/up.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/doubleZ0108/Operating-System/f00305ef02f4c4b7a92252947dcd559e7602c434/进程管理_电梯调度/Resources/Button/up.png
--------------------------------------------------------------------------------
/进程管理_电梯调度/Resources/Button/up_hover.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/doubleZ0108/Operating-System/f00305ef02f4c4b7a92252947dcd559e7602c434/进程管理_电梯调度/Resources/Button/up_hover.png
--------------------------------------------------------------------------------
/进程管理_电梯调度/Resources/Button/up_pressed.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/doubleZ0108/Operating-System/f00305ef02f4c4b7a92252947dcd559e7602c434/进程管理_电梯调度/Resources/Button/up_pressed.png
--------------------------------------------------------------------------------
/进程管理_电梯调度/Resources/Figure/people.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/doubleZ0108/Operating-System/f00305ef02f4c4b7a92252947dcd559e7602c434/进程管理_电梯调度/Resources/Figure/people.png
--------------------------------------------------------------------------------
/进程管理_电梯调度/Resources/Icon/elevator.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/doubleZ0108/Operating-System/f00305ef02f4c4b7a92252947dcd559e7602c434/进程管理_电梯调度/Resources/Icon/elevator.ico
--------------------------------------------------------------------------------
/进程管理_电梯调度/Resources/Icon/icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/doubleZ0108/Operating-System/f00305ef02f4c4b7a92252947dcd559e7602c434/进程管理_电梯调度/Resources/Icon/icon.png
--------------------------------------------------------------------------------
/进程管理_电梯调度/Src/dispatch.py:
--------------------------------------------------------------------------------
1 | from PyQt5 import QtCore, QtGui, QtWidgets
2 | from PyQt5.QtCore import *
3 | from PyQt5.QtCore import QTimer
4 |
5 | from myElevatorInterface import *
6 | import numpy as np
7 | import time, threading
8 |
9 | INFINITE = 100 # 定义"无穷大量"
10 |
11 | OPEN = 0 # 开门装填
12 | CLOSED = 1 # 关门状态
13 |
14 | STANDSTILL = 0 # 静止状态
15 | RUNNING_UP = 1 # 电梯上行状态
16 | RUNNING_DOWN = 2 # 电梯下行状态
17 |
18 | NOPE = 0 # 空动画
19 | READYSTART = 1 # 电梯即将运动
20 | READYSTOP = 2 # 电梯即将停止
21 |
22 | GOUP = 1 # 用户要上行
23 | GODOWN = 2 # 用户要下行
24 |
25 |
26 | class Controler(object):
27 | def __init__(self, Elev):
28 | # 与界面文件建立连接
29 | self.elev = Elev
30 |
31 | # 创建定时器, 1s中更新一次电梯状态
32 | self.timer = QTimer()
33 | self.timer.timeout.connect(self.updateElevState)
34 | self.timer.start(1000)
35 |
36 | # 5个电梯内部消息列表(用列表代替队列)
37 | self.messQueue = []
38 | for i in range(0, 5):
39 | self.messQueue.append([])
40 | # 5个电梯内部不顺路消息列表
41 | self.messQueue_reverse = []
42 | for i in range(0, 5):
43 | self.messQueue_reverse.append([])
44 |
45 | # 警报器槽函数
46 | def warnCtrl(self, whichelev):
47 | self.elev.elevEnabled[whichelev] = False # 该电梯禁用
48 |
49 | self.elev.warnbtn[whichelev].setEnabled(False) # 报警键禁用
50 | self.elev.gridLayoutWidget[whichelev].setEnabled(False) # 楼层按键禁用
51 | self.elev.openbtn[whichelev].setEnabled(False) # 开门键禁用
52 | self.elev.closebtn[whichelev].setEnabled(False) # 关门键禁用
53 | self.elev.elevator_back[whichelev].setEnabled(False) # 电梯背景禁用
54 | self.elev.elevator_front[2 * whichelev].setEnabled(False) # 电梯前门禁用
55 | self.elev.elevator_front[2 * whichelev + 1].setEnabled(False) # 电梯前门禁用
56 | self.elev.elevator_Anim[2 * whichelev].stop() # 停止动画
57 | self.elev.elevator_Anim[2 * whichelev + 1].stop() # 停止动画
58 | self.elev.label[whichelev].setEnabled(False) # 电梯文字禁用
59 | self.elev.lcdNumber[whichelev].setEnabled(False) # 数码管禁用
60 | self.elev.stateshow[whichelev].setEnabled(False) # 上下行标志禁用
61 | self.elev.updoorbtn[whichelev].setEnabled(False) # 门口上行按钮禁用
62 | self.elev.downdoorbtn[whichelev].setEnabled(False) # 门口下行按钮禁用
63 |
64 | # 五部电梯全部禁用
65 | arr = np.array(self.elev.elevEnabled)
66 | if ((arr == False).all()):
67 | self.elev.comboBox.setEnabled(False) # 下拉框禁用
68 | self.elev.chooselabel.setEnabled(False) # 文字禁用
69 | self.elev.upbtn.setEnabled(False) # 上行按钮禁用
70 | self.elev.downbtn.setEnabled(False) # 下行按钮禁用
71 |
72 | time.sleep(0.5)
73 | self.MessBox = QtWidgets.QMessageBox.information(self.elev, "警告", "所有电梯已损坏!")
74 |
75 | # 开关门槽函数
76 | def doorCtrl(self, whichelev, whichcommand):
77 | if whichcommand == 0: # 如果用户要开门
78 | if self.elev.doorState[whichelev] == CLOSED and self.elev.elevState[
79 | whichelev] == STANDSTILL: # 如果当前门是关闭状态并且电梯是静止的
80 | self.elev.doorState[whichelev] = OPEN # 先将门状态更新为打开
81 | self.elev.elevEnabled[whichelev] = False
82 |
83 | self.openDoor_Anim(whichelev)
84 |
85 | else: # 如果用户要关门
86 | if self.elev.doorState[whichelev] == OPEN and self.elev.elevState[
87 | whichelev] == STANDSTILL: # 如果当前门是打开状态并且电梯是静止的
88 | self.elev.doorState[whichelev] = CLOSED # 先将门状态更新为关闭
89 | self.elev.elevEnabled[whichelev] = True
90 |
91 | #将电梯门前的上下行按键熄灭
92 | for i in range(0, 5):
93 | if self.elev.elevEnabled[i]:
94 | self.elev.updoorbtn[i].setStyleSheet("QPushButton{border-image: url(Resources/Button/doorup.png)}"
95 | "QPushButton:hover{border-image: url(Resources/Button/doorup_hover.png)}"
96 | "QPushButton:pressed{border-image: url(Resources/Button/doorup_pressed.png)}")
97 | self.elev.downdoorbtn[i].setStyleSheet("QPushButton{border-image: url(Resources/Button/doordown.png)}"
98 | "QPushButton:hover{border-image: url(Resources/Button/doordown_hover.png)}"
99 | "QPushButton:pressed{border-image: url(Resources/Button/doordown_pressed.png)}")
100 | self.elev.updoorbtn[i].setEnabled(True)
101 | self.elev.downdoorbtn[i].setEnabled(True)
102 | self.closeDoor_Anim(whichelev)
103 |
104 | # 开门动画
105 | def openDoor_Anim(self, whichelev):
106 | self.elev.elevator_Anim[2 * whichelev].setDirection(QAbstractAnimation.Forward) # 正向设定动画
107 | self.elev.elevator_Anim[2 * whichelev + 1].setDirection(QAbstractAnimation.Forward)
108 | self.elev.elevator_Anim[2 * whichelev].start() # 开始播放
109 | self.elev.elevator_Anim[2 * whichelev + 1].start()
110 |
111 | # 关门动画
112 | def closeDoor_Anim(self, whichelev):
113 | self.elev.elevator_Anim[2 * whichelev].setDirection(QAbstractAnimation.Backward) # 反向设定动画
114 | self.elev.elevator_Anim[2 * whichelev + 1].setDirection(QAbstractAnimation.Backward)
115 | self.elev.elevator_Anim[2 * whichelev].start() # 开始播放
116 | self.elev.elevator_Anim[2 * whichelev + 1].start()
117 |
118 | # 小人进电梯动画
119 | def figureIn_Anim(self, whichelev):
120 | self.elev.figure[whichelev].setVisible(True)
121 | self.elev.figure_Anim[whichelev].setDirection(QAbstractAnimation.Forward)
122 | self.elev.figure_Anim[whichelev].start()
123 |
124 | s = threading.Timer(1.5, self.setDoorTop, (whichelev,)) # 1.5秒之后把门至于顶层
125 | s.start()
126 |
127 | # 小人出电梯动画
128 | def figureOut_Anim(self, whichelev):
129 | self.elev.figure[whichelev].setVisible(True)
130 | self.elev.figure_Anim[whichelev].setDirection(QAbstractAnimation.Backward)
131 | self.elev.figure_Anim[whichelev].start()
132 |
133 | s = threading.Timer(1, self.setFigureTop, (whichelev,)) # 1s之后将人至于顶层
134 | s.start()
135 |
136 | # 将门至于顶层
137 | def setDoorTop(self, whichelev):
138 | self.elev.elevator_front[2 * whichelev].raise_()
139 | self.elev.elevator_front[2 * whichelev + 1].raise_()
140 |
141 | # 将小人至于顶层
142 | def setFigureTop(self, whichelev):
143 | self.elev.figure[whichelev].raise_()
144 | self.elev.figure[whichelev].setVisible(False)
145 |
146 | # 内命令电梯运动
147 | def elevMove(self, whichelev, dest):
148 |
149 | nowFloor = self.elev.elevNow[whichelev] # 获取当前电梯位置
150 |
151 | if nowFloor < dest: # 如果按键大于当前楼层
152 | if self.elev.elevState[whichelev] == STANDSTILL: # 电梯处于静止状态
153 | self.messQueue[whichelev].append(dest) # 将目标楼层加入 消息队列
154 |
155 | else:
156 | if self.elev.elevState[whichelev] == RUNNING_UP: # 电梯正在向上运行
157 | self.messQueue[whichelev].append(dest) # 将目标楼层加入 消息队列并排序
158 | self.messQueue[whichelev].sort()
159 | elif self.elev.elevState[whichelev] == RUNNING_DOWN: # 电梯正在向下运行
160 | self.messQueue_reverse[whichelev].append(dest) # 将目标楼层加入 不顺路消息队列并排序
161 | self.messQueue_reverse[whichelev].sort()
162 |
163 | elif nowFloor > dest:
164 | if self.elev.elevState[whichelev] == STANDSTILL:
165 | self.messQueue[whichelev].append(dest) # 将目标楼层加入 消息队列
166 |
167 | else:
168 | if self.elev.elevState[whichelev] == RUNNING_DOWN:
169 | self.messQueue[whichelev].append(dest) # 将目标楼层加入 消息队列并反向排序
170 | self.messQueue[whichelev].sort()
171 | self.messQueue[whichelev].reverse()
172 | elif self.elev.elevState[whichelev] == RUNNING_UP:
173 | self.messQueue_reverse[whichelev].append(dest) # 将目标楼层加入 不顺路消息队列并反向排序
174 | self.messQueue_reverse[whichelev].sort()
175 | self.messQueue_reverse[whichelev].reverse()
176 |
177 | else: # 如果按键就为当前楼层
178 | if self.elev.elevState[whichelev] == STANDSTILL: # 电梯静止 => 打开门(并等待用户自行关闭)
179 | self.elev.doorState[whichelev] = OPEN
180 | self.openDoor_Anim(whichelev)
181 |
182 | button = self.elev.findChild(QtWidgets.QPushButton,
183 | "button {0} {1}".format(whichelev, nowFloor)) # 恢复按键背景并重新允许点击
184 | button.setStyleSheet("")
185 | button.setEnabled(True)
186 |
187 | # 外命令电梯调度
188 | def chooseCtrl(self, whichfloor, choice):
189 |
190 | # region 初步筛选没损坏的电梯
191 | EnabledList = []
192 | for i in range(0, 5):
193 | if self.elev.elevEnabled[i]:
194 | EnabledList.append(i)
195 | print(EnabledList)
196 | # endregion
197 |
198 | # region 计算每部可用电梯的"可调度性"
199 | dist = [INFINITE] * 5 # 可使用电梯距离用户的距离
200 | for EnabledElev in EnabledList:
201 | if self.elev.elevState[EnabledElev] == RUNNING_UP and choice == GOUP and whichfloor > self.elev.elevNow[
202 | EnabledElev]: # 向上顺路
203 | dist[EnabledElev] = whichfloor - self.elev.elevNow[EnabledElev]
204 |
205 | elif self.elev.elevState[EnabledElev] == RUNNING_DOWN and choice == GODOWN and whichfloor < \
206 | self.elev.elevNow[EnabledElev]: # 向下顺路
207 | dist[EnabledElev] = self.elev.elevNow[EnabledElev] - whichfloor
208 |
209 | elif self.elev.elevState[EnabledElev] == STANDSTILL: # 该电梯此时静止
210 | dist[EnabledElev] = abs(self.elev.elevNow[EnabledElev] - whichfloor)
211 | # endregion
212 |
213 | BestElev = dist.index(min(dist)) # 选择可调度性最好的电梯作为最佳电梯
214 | if dist[BestElev] == 0: # 如果最佳电梯就在用户选择的楼层
215 | self.elev.doorState[BestElev] = OPEN # 打开门并等待用户自行关闭
216 | self.openDoor_Anim(BestElev)
217 |
218 | else:
219 | self.messQueue[BestElev].append(whichfloor) # 加入该最佳电梯的消息队列
220 | button = self.elev.findChild(QtWidgets.QPushButton,
221 | "button {0} {1}".format(BestElev, whichfloor)) # 将用户的目标楼层设定为特殊颜色
222 | button.setStyleSheet("background-color: rgb(11, 15, 255);")
223 | button.setEnabled(False)
224 |
225 | # 更新电梯状态
226 | def updateElevState(self):
227 | # print('timer clock......')
228 |
229 | for i in range(0, len(self.messQueue)): # 遍历五部电梯
230 | if len(self.messQueue[i]): # 某个电梯的消息队列不为空
231 |
232 | if self.elev.doorState[i] == OPEN: # 如果电梯门是打开的 => 等待电梯关门
233 | continue
234 |
235 | elif self.elev.elevState[i] == STANDSTILL: # 电梯处于静止状态
236 | self.openDoor_Anim(i)
237 | self.figureIn_Anim(i)
238 |
239 | if self.elev.elevNow[i] < self.messQueue[i][0]: # 根据即将运行的方向更新电梯状态
240 | self.elev.elevState[i] = RUNNING_UP
241 | elif self.elev.elevNow[i] > self.messQueue[i][0]:
242 | self.elev.elevState[i] = RUNNING_DOWN
243 |
244 | self.elev.animState[i] = READYSTART # 动画变为就绪运行状态
245 |
246 | elif self.elev.animState[i] == READYSTART: # 动画处于就绪运行状态
247 | self.closeDoor_Anim(i)
248 | self.elev.animState[i] = NOPE # 动画变为空状态
249 |
250 | elif self.elev.animState[i] == READYSTOP: # 动画处于就绪停止状态
251 | self.messQueue[i].pop(0) # 结束该命令的处理
252 | self.closeDoor_Anim(i)
253 | self.elev.animState[i] = NOPE # 动画变为空状态
254 | self.elev.elevState[i] = STANDSTILL # 电梯变为静止状态
255 | self.elev.stateshow[i].setStyleSheet("QGraphicsView{border-image: url(Resources/Button/state.png)}")
256 |
257 | else:
258 | destFloor = self.messQueue[i][0] # 获取第一个目标楼层
259 |
260 | if self.elev.elevNow[i] < destFloor: # 向上运动
261 | self.elev.elevState[i] = RUNNING_UP
262 | self.elev.stateshow[i].setStyleSheet(
263 | "QGraphicsView{border-image: url(Resources/Button/state_up.png)}")
264 | self.elev.elevNow[i] = self.elev.elevNow[i] + 1 # 将当前楼层加一并设置数码管显示
265 | self.elev.lcdNumber[i].setProperty("value", self.elev.elevNow[i])
266 |
267 | elif self.elev.elevNow[i] > destFloor: # 向下运动
268 | self.elev.elevState[i] = RUNNING_DOWN
269 | self.elev.stateshow[i].setStyleSheet(
270 | "QGraphicsView{border-image: url(Resources/Button/state_down.png)}")
271 | self.elev.elevNow[i] = self.elev.elevNow[i] - 1 # 将当前楼层减一并设置数码管显示
272 | self.elev.lcdNumber[i].setProperty("value", self.elev.elevNow[i])
273 |
274 | else: # 电梯到达目的地
275 | self.openDoor_Anim(i)
276 | self.figureOut_Anim(i)
277 | self.elev.animState[i] = READYSTOP # 到达目的地 => 动画变为就绪停止状态
278 |
279 | button = self.elev.findChild(QtWidgets.QPushButton,
280 | "button {0} {1}".format(i, self.elev.elevNow[i])) # 恢复该按钮的状态
281 | button.setStyleSheet("")
282 | button.setEnabled(True)
283 |
284 | elif len(self.messQueue_reverse[i]): # 如果消息队列为空 & 不顺路消息队列不为空
285 | self.messQueue[i] = self.messQueue_reverse[i].copy() # 交替两个队列
286 | self.messQueue_reverse[i].clear()
287 |
288 | # 电梯在运行过程中禁止点击报警键
289 | for i in range(0, 5):
290 | if self.elev.gridLayoutWidget[i].isEnabled(): # 如果这个电梯没被禁用
291 | if self.elev.elevState[i] == STANDSTILL: # 如果电梯是静止的
292 | self.elev.warnbtn[i].setEnabled(True)
293 | else:
294 | self.elev.warnbtn[i].setEnabled(False)
295 |
--------------------------------------------------------------------------------
/进程管理_电梯调度/Src/myElevator.py:
--------------------------------------------------------------------------------
1 | import sys, threading
2 | from PyQt5.QtWidgets import *
3 | from PyQt5.QtGui import QIcon
4 |
5 | from myElevatorInterface import *
6 | from dispatch import *
7 |
8 |
9 | class mywindow(QtWidgets.QMainWindow, Ui_MainWindow):
10 | def __init__(self):
11 | super(mywindow, self).__init__()
12 | self.setupUi(self)
13 | self.setWindowTitle('myElevator')
14 | self.setWindowIcon(QIcon('Resources/Icon/icon.png'))
15 |
16 |
17 | if __name__ == '__main__':
18 | app = QApplication(sys.argv)
19 |
20 | window = mywindow()
21 | window.show()
22 |
23 | sys.exit(app.exec())
24 |
--------------------------------------------------------------------------------
/进程管理_电梯调度/Src/myElevatorInterface.py:
--------------------------------------------------------------------------------
1 | # -*- coding: utf-8 -*-
2 |
3 | from PyQt5 import QtCore, QtGui, QtWidgets
4 | from dispatch import Controler
5 | from PyQt5.QtCore import *
6 |
7 | OPEN = 0 # 开门状态
8 | CLOSED = 1 # 关门状态
9 |
10 | STANDSTILL = 0 # 静止状态
11 | RUNNING_UP = 1 # 电梯上行状态
12 | RUNNING_DOWN = 2 # 电梯下行状态
13 |
14 | NOPE = 0 # 空动画
15 | READYSTART = 1 # 电梯即将运动
16 | READYSTOP = 2 # 电梯即将停止
17 |
18 | GOUP = 1 # 用户要上行
19 | GODOWN = 2 # 用户要下行
20 |
21 |
22 | class Ui_MainWindow(object):
23 | def __init__(self):
24 | self.Ctrl = Controler(self) # 与调度文件建立连接
25 |
26 | self.elevEnabled = [True] * 5 # 电梯状态(可使用/禁用)标志位
27 | self.doorState = [CLOSED] * 5 # 电梯门状态(开门/关门)标志位
28 | self.elevState = [STANDSTILL] * 5 # 电梯状态(运行向上/运行向下/静止)标志位
29 | self.animState = [NOPE] * 5 # 动画播放状态(空/即将运动/即将停止)标志位
30 | self.elevNow = [1] * 5 # 电梯楼层
31 |
32 | self.wall = [] # 墙模型
33 | self.elevator_back = [] # 电梯模型
34 | self.elevator_front = []
35 | self.elevator_Anim = []
36 | self.label = []
37 | self.lcdNumber = [] # 数码管模型
38 | self.stateshow = [] # 上下行标志模型
39 | self.updoorbtn = [] # 门口上下行按钮模型
40 | self.downdoorbtn = []
41 | self.warnbtn = [] # 报警器模型
42 | self.gridLayoutWidget = [] # 楼层按键模型
43 | self.gridLayout = []
44 | self.openbtn = [] # 开关键模型
45 | self.closebtn = []
46 | self.figure = [] # 小人模型
47 | self.figure_Anim = []
48 |
49 | def setupUi(self, MainWindow):
50 | MainWindow.setObjectName("MainWindow")
51 | MainWindow.resize(1400, 700)
52 | MainWindow.setStyleSheet("")
53 | self.centralwidget = QtWidgets.QWidget(MainWindow)
54 | self.centralwidget.setObjectName("centralwidget")
55 |
56 | # region 墙模型
57 | wall_pos = [10, 280, 560, 840, 1120, 1390]
58 |
59 | for i in range(0, len(wall_pos)):
60 | self.wall.append(QtWidgets.QGraphicsView(self.centralwidget))
61 | self.wall[i].setGeometry(QtCore.QRect(wall_pos[i], 120, 10, 560))
62 | self.wall[i].setAutoFillBackground(False)
63 | self.wall[i].setStyleSheet("background-color: rgb(0, 0, 0);")
64 | self.wall[i].setObjectName("wall" + str(i))
65 | # endregion
66 |
67 | # region 电梯模型
68 | elevator_pos = [30, 300, 580, 860, 1140]
69 |
70 | for i in range(0, len(elevator_pos)):
71 | # 后面的电梯背景
72 | self.elevator_back.append(QtWidgets.QGraphicsView(self.centralwidget))
73 | self.elevator_back[i].setGeometry(QtCore.QRect(elevator_pos[i], 470, 131, 161))
74 | self.elevator_back[i].setStyleSheet("background-color: rgb(87, 87, 87);")
75 | self.elevator_back[i].setObjectName("elevator_back" + str(i))
76 |
77 | # 前面的两扇电梯门
78 | self.elevator_front.append(QtWidgets.QGraphicsView(self.centralwidget))
79 | self.elevator_front[2 * i].setGeometry(QtCore.QRect(elevator_pos[i], 470, 64, 161))
80 | self.elevator_front[2 * i].setStyleSheet("background-color: rgb(160, 160, 160);")
81 | self.elevator_front[2 * i].setObjectName("elevator_front" + str(2 * i))
82 | self.elevator_Anim.append(QPropertyAnimation(self.elevator_front[2 * i], b"geometry"))
83 | self.elevator_Anim[2 * i].setDuration(1000) # 设定动画时间
84 | self.elevator_Anim[2 * i].setStartValue(QtCore.QRect(elevator_pos[i], 470, 64, 161)) # 设置起始大小
85 | self.elevator_Anim[2 * i].setEndValue(QtCore.QRect(elevator_pos[i], 470, 8, 161)) # 设置终止大小
86 |
87 | self.elevator_front.append(QtWidgets.QGraphicsView(self.centralwidget))
88 | self.elevator_front[2 * i + 1].setGeometry(QtCore.QRect(elevator_pos[i] + 67, 470, 64, 161))
89 | self.elevator_front[2 * i + 1].setStyleSheet("background-color: rgb(160, 160, 160);")
90 | self.elevator_front[2 * i + 1].setObjectName("elevator_front" + str(2 * i + 1))
91 | self.elevator_Anim.append(QPropertyAnimation(self.elevator_front[2 * i + 1], b"geometry"))
92 | self.elevator_Anim[2 * i + 1].setDuration(1000)
93 | self.elevator_Anim[2 * i + 1].setStartValue(QtCore.QRect(elevator_pos[i] + 67, 470, 64, 161))
94 | self.elevator_Anim[2 * i + 1].setEndValue(QtCore.QRect(elevator_pos[i] + 123, 470, 8, 161))
95 | # endregion
96 |
97 | # region 电梯文字模型
98 | font = QtGui.QFont()
99 | font.setFamily("AcadEref")
100 | font.setPointSize(10)
101 | font.setBold(False)
102 | font.setItalic(False)
103 | font.setWeight(50)
104 |
105 | label_pos = [70, 340, 620, 900, 1180]
106 | for i in range(0, len(label_pos)):
107 | self.label.append(QtWidgets.QLabel(self.centralwidget))
108 | self.label[i].setGeometry(QtCore.QRect(label_pos[i], 640, 51, 21))
109 | self.label[i].setFont(font)
110 | self.label[i].setStyleSheet("font: 10pt \"AcadEref\";\n"
111 | "background-color: rgb(160, 160, 160);")
112 | self.label[i].setObjectName("label" + str(i))
113 | # endregion
114 |
115 | # region 电梯楼层数码管
116 | lcdNumber_pos = [50, 320, 600, 880, 1160]
117 | for i in range(0, len(lcdNumber_pos)):
118 | self.lcdNumber.append(QtWidgets.QLCDNumber(self.centralwidget))
119 | self.lcdNumber[i].setGeometry(QtCore.QRect(lcdNumber_pos[i], 420, 51, 41))
120 | self.lcdNumber[i].setDigitCount(2)
121 | self.lcdNumber[i].setProperty("value", 1.0) # 设置初始楼层为1层
122 | self.lcdNumber[i].setObjectName("lcdNumber" + str(i))
123 | # endregion
124 |
125 | # region 电梯上下行标志
126 | stateshow_pos = [95, 365, 645, 925, 1205]
127 | for i in range(0, len(stateshow_pos)):
128 | self.stateshow.append(QtWidgets.QGraphicsView(self.centralwidget))
129 | self.stateshow[i].setGeometry(QtCore.QRect(stateshow_pos[i], 410, 71, 61))
130 | self.stateshow[i].setStyleSheet("QGraphicsView{border-image: url(Resources/Button/state.png)}")
131 | self.stateshow[i].setObjectName("stateshow" + str(i))
132 | # endregion
133 |
134 | # region 门口按钮
135 | doorbtn_pos = [157, 427, 707, 987, 1267]
136 |
137 | for i in range(0, len(doorbtn_pos)):
138 | # 上行按钮
139 | self.updoorbtn.append(QtWidgets.QPushButton(self.centralwidget))
140 | self.updoorbtn[i].setGeometry(QtCore.QRect(doorbtn_pos[i], 550, 35, 30))
141 | self.updoorbtn[i].setStyleSheet("QPushButton{border-image: url(Resources/Button/doorup.png)}"
142 | "QPushButton:hover{border-image: url(Resources/Button/doorup_hover.png)}"
143 | "QPushButton:pressed{border-image: url(Resources/Button/doorup_pressed.png)}")
144 | self.updoorbtn[i].setObjectName("updoorbtn" + str(i))
145 |
146 | # 上行按钮
147 | self.downdoorbtn.append(QtWidgets.QPushButton(self.centralwidget))
148 | self.downdoorbtn[i].setGeometry(QtCore.QRect(doorbtn_pos[i], 585, 35, 30))
149 | self.downdoorbtn[i].setStyleSheet("QPushButton{border-image: url(Resources/Button/doordown.png)}"
150 | "QPushButton:hover{border-image: url(Resources/Button/doordown_hover.png)}"
151 | "QPushButton:pressed{border-image: url(Resources/Button/doordown_pressed.png)}")
152 | self.downdoorbtn[i].setObjectName("downdoorbtn" + str(i))
153 |
154 | self.updoorbtn[i].clicked.connect(MainWindow.chooseClick) # 绑定外命令槽函数
155 | self.downdoorbtn[i].clicked.connect(MainWindow.chooseClick)
156 | # endregion
157 |
158 | # region 报警器模型
159 | warnbtn_pos = [190, 460, 740, 1020, 1300]
160 | for i in range(0, len(warnbtn_pos)):
161 | self.warnbtn.append(QtWidgets.QPushButton(self.centralwidget))
162 | self.warnbtn[i].setGeometry(QtCore.QRect(warnbtn_pos[i] + 10, 620, 56, 31))
163 | self.warnbtn[i].setStyleSheet("background-color: rgb(180, 0, 0);")
164 | self.warnbtn[i].setObjectName("warnbtn" + str(i))
165 |
166 | # 绑定报警器槽函数
167 | for i in range(0, len(self.warnbtn)):
168 | self.warnbtn[i].clicked.connect(MainWindow.warningClick)
169 |
170 | # endregion
171 |
172 | # region 楼层按键建模
173 | gridLayoutWidget_pos = [180, 450, 730, 1010, 1290]
174 |
175 | for i in range(0, len(gridLayoutWidget_pos)):
176 | self.gridLayoutWidget.append(QtWidgets.QWidget(self.centralwidget))
177 | self.gridLayoutWidget[i].setGeometry(QtCore.QRect(gridLayoutWidget_pos[i] + 10, 120, 81, 451))
178 | self.gridLayoutWidget[i].setObjectName("gridLayoutWidget" + str(i))
179 | self.gridLayout.append(QtWidgets.QGridLayout(self.gridLayoutWidget[i]))
180 | self.gridLayout[i].setContentsMargins(0, 0, 0, 0)
181 | self.gridLayout[i].setObjectName("gridLayout" + str(i))
182 |
183 | names = ['19', '20', '17', '18', '15', '16', '13', '14', '11', '12', '9', '10', '7', '8', '5', '6', '3', '4',
184 | '1', '2']
185 |
186 | positions = [(i, j) for i in range(10) for j in range(2)] # 构造十行两列的格子
187 | for i in range(0, len(gridLayoutWidget_pos)):
188 | for position, name in zip(positions, names):
189 | button = QtWidgets.QPushButton(name)
190 | button.setObjectName("button " + str(i) + ' ' + name)
191 | button.setStyleSheet("")
192 | button.clicked.connect(MainWindow.btnClick) # 绑定楼层按键槽函数
193 | self.gridLayout[i].addWidget(button, *position) # 放到布局里
194 | # endregion
195 |
196 | # region 开关键模型
197 | openbtn_pos = [180, 450, 730, 1010, 1290]
198 | closebtn_pos = [230, 500, 780, 1060, 1340]
199 |
200 | for i in range(0, len(openbtn_pos)):
201 | self.openbtn.append(QtWidgets.QPushButton(self.centralwidget))
202 | self.openbtn[i].setGeometry(QtCore.QRect(openbtn_pos[i] + 10, 580, 31, 31))
203 | self.openbtn[i].setObjectName("openbtn" + str(i))
204 | self.closebtn.append(QtWidgets.QPushButton(self.centralwidget))
205 | self.closebtn[i].setGeometry(QtCore.QRect(closebtn_pos[i] + 10, 580, 31, 31))
206 | self.closebtn[i].setObjectName("closebtn" + str(i))
207 |
208 | self.openbtn[i].clicked.connect(MainWindow.doorClick) # 绑定门开关键槽函数
209 | self.closebtn[i].clicked.connect(MainWindow.doorClick)
210 | # endregion
211 |
212 | # region 下拉框模型
213 | self.comboBox = QtWidgets.QComboBox(self.centralwidget)
214 | self.comboBox.setGeometry(QtCore.QRect(630, 55, 111, 31))
215 | self.comboBox.setObjectName("comboBox")
216 | for i in range(0, 20):
217 | self.comboBox.addItem(str(i + 1)) # 加入楼层信息
218 |
219 | self.chooselabel = QtWidgets.QLabel(self.centralwidget)
220 | self.chooselabel.setGeometry(QtCore.QRect(450, 60, 161, 21))
221 | self.chooselabel.setObjectName("chooselabel")
222 |
223 | # 上行按钮
224 | self.upbtn = QtWidgets.QPushButton(self.centralwidget)
225 | self.upbtn.setGeometry(QtCore.QRect(760, 40, 51, 51))
226 | self.upbtn.setStyleSheet("QPushButton{border-image: url(Resources/Button/up.png)}"
227 | "QPushButton:hover{border-image: url(Resources/Button/up_hover.png)}"
228 | "QPushButton:pressed{border-image: url(Resources/Button/up_pressed.png)}")
229 | self.upbtn.setObjectName("upbtn")
230 |
231 | # 上行按钮
232 | self.downbtn = QtWidgets.QPushButton(self.centralwidget)
233 | self.downbtn.setGeometry(QtCore.QRect(810, 40, 51, 51))
234 | self.downbtn.setStyleSheet("QPushButton{border-image: url(Resources/Button/down.png)}"
235 | "QPushButton:hover{border-image: url(Resources/Button/down_hover.png)}"
236 | "QPushButton:pressed{border-image: url(Resources/Button/down_pressed.png)}")
237 | self.downbtn.setObjectName("downbtn")
238 |
239 | self.upbtn.clicked.connect(MainWindow.chooseClick) # 绑定外命令槽函数
240 | self.downbtn.clicked.connect(MainWindow.chooseClick)
241 | # endregion
242 |
243 | # region 小人模型
244 | figure_pos = [30, 300, 580, 860, 1140]
245 |
246 | for i in range(0, len(figure_pos)):
247 | self.figure.append(QtWidgets.QGraphicsView(self.centralwidget))
248 | self.figure[i].setGeometry(QtCore.QRect(figure_pos[i] - 20, 590, 71, 71))
249 | self.figure[i].setStyleSheet("QGraphicsView{border-image: url(Resources/Figure/people.png)}")
250 | self.figure[i].setVisible(False)
251 | self.figure[i].setObjectName("figure" + str(i))
252 | self.figure_Anim.append(QPropertyAnimation(self.figure[i], b"geometry"))
253 | self.figure_Anim[i].setDuration(1500)
254 | self.figure_Anim[i].setStartValue(QtCore.QRect(figure_pos[i] - 20, 590, 71, 71))
255 | self.figure_Anim[i].setEndValue(QtCore.QRect(figure_pos[i] + 10, 510, 111, 121))
256 | # endregion
257 |
258 | MainWindow.setCentralWidget(self.centralwidget)
259 | self.menubar = QtWidgets.QMenuBar(MainWindow)
260 | self.menubar.setGeometry(QtCore.QRect(0, 0, 1400, 18))
261 | self.menubar.setObjectName("menubar")
262 | MainWindow.setMenuBar(self.menubar)
263 | self.statusbar = QtWidgets.QStatusBar(MainWindow)
264 | self.statusbar.setObjectName("statusbar")
265 | MainWindow.setStatusBar(self.statusbar)
266 |
267 | self.retranslateUi(MainWindow)
268 |
269 | QtCore.QMetaObject.connectSlotsByName(MainWindow)
270 |
271 | def retranslateUi(self, MainWindow):
272 | _translate = QtCore.QCoreApplication.translate
273 | MainWindow.setWindowTitle(_translate("MainWindow", "MainWindow"))
274 | self.chooselabel.setText(_translate("MainWindow", "请选择你所在的楼层"))
275 |
276 | for i in range(0, len(self.label)):
277 | self.label[i].setText(_translate("MainWindow", "电梯" + str(i)))
278 | self.warnbtn[i].setText(_translate("MainWindow", "报警器"))
279 | self.openbtn[i].setText(_translate("MainWindow", "开"))
280 | self.closebtn[i].setText(_translate("MainWindow", "关"))
281 |
282 | # 报警器槽函数
283 | def warningClick(self):
284 | which_warnbtn = int(self.sender().objectName()[-1])
285 | print("点击了{0}号报警器".format(which_warnbtn))
286 | self.warnbtn[which_warnbtn].setStyleSheet("background-color: rgb(255, 255, 255);")
287 | self.MessBox = QtWidgets.QMessageBox.information(self.warnbtn[int(which_warnbtn)], "警告", # 弹出警告框
288 | "第" + str(which_warnbtn) + "号电梯已损坏, 不能继续使用")
289 | self.warnbtn[which_warnbtn].setStyleSheet("background-color: rgb(180, 0, 0);")
290 |
291 | self.Ctrl.warnCtrl(which_warnbtn) # 调用控制器进行warnCtrl处理
292 |
293 | # 楼层按键槽函数
294 | def btnClick(self):
295 | whichbtn = self.sender()
296 |
297 | btn_name = whichbtn.objectName()
298 | buf = [int(s) for s in btn_name.split() if s.isdigit()] # 提取字符串中的数字
299 | whichelev = buf[0]
300 | whichfloor = buf[1]
301 | print("{0}号电梯, {1}按键被按".format(whichelev, whichfloor))
302 |
303 | whichbtn.setStyleSheet("background-color: rgb(255, 150, 3);") # 改变按钮背景颜色(模拟点击状态)
304 | whichbtn.setEnabled(False) # 将该按钮设置为不可点击状态
305 | self.Ctrl.elevMove(whichelev, whichfloor) # 调用控制器进行elevMove处理
306 |
307 | # 外命令选择槽函数
308 | def chooseClick(self):
309 | whichfloor = int(self.comboBox.currentText())
310 | whichbtn = self.sender().objectName()
311 |
312 | if whichbtn[0] == 'd':
313 | if whichbtn != "downbtn": # 如果是电梯门前的按钮
314 | for i in range(0, len(self.downdoorbtn)):
315 | if self.elevEnabled[i]:
316 | self.downdoorbtn[i].setStyleSheet(
317 | "QPushButton{border-image: url(Resources/Button/doordown_pressed.png)}")
318 | self.downdoorbtn[i].setEnabled(False)
319 | choice = GODOWN
320 | else:
321 | if whichbtn != "upbtn": # 如果是电梯门前的按钮
322 | for i in range(0, len(self.downdoorbtn)):
323 | if self.elevEnabled[i]:
324 | self.updoorbtn[i].setStyleSheet(
325 | "QPushButton{border-image: url(Resources/Button/doorup_pressed.png)}")
326 | self.updoorbtn[i].setEnabled(False)
327 |
328 | choice = GOUP
329 |
330 | print("用户选择了 {0} {1}".format(whichfloor, choice))
331 |
332 | self.Ctrl.chooseCtrl(whichfloor, choice) # 调用控制器进行chooseCtrl处理
333 |
334 | # 开关门槽函数
335 | def doorClick(self):
336 | objectName = self.sender().objectName()
337 | whichelev = int(objectName[-1])
338 | whichcommand = 0 if objectName[0] == 'o' else 1 # 0 => 开门 1 => 关门
339 | print("{0}号电梯, 命令是{1}".format(whichelev, whichcommand))
340 |
341 | self.Ctrl.doorCtrl(whichelev, whichcommand) # 调用控制器进行doorCtrl处理
342 |
--------------------------------------------------------------------------------
/进程管理_电梯调度/电梯调度_设计方案报告.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/doubleZ0108/Operating-System/f00305ef02f4c4b7a92252947dcd559e7602c434/进程管理_电梯调度/电梯调度_设计方案报告.pdf
--------------------------------------------------------------------------------