├── .vs └── 文件系统 │ └── v15 │ ├── .suo │ ├── Browse.VC.db │ └── ipch │ └── AutoPCH │ ├── 7e01b5698d554240 │ └── 源.ipch │ └── 89b2dfd1f3d27413 │ └── FILESYSTEM.ipch ├── Debug ├── 文件系统.exe ├── 文件系统.ilk └── 文件系统.pdb ├── README.md ├── 文件系统.sln └── 文件系统 ├── Debug ├── vc141.idb ├── vc141.pdb ├── 文件系统.log ├── 文件系统.tlog │ ├── CL.command.1.tlog │ ├── CL.read.1.tlog │ ├── CL.write.1.tlog │ ├── link.command.1.tlog │ ├── link.read.1.tlog │ ├── link.write.1.tlog │ └── 文件系统.lastbuildstate ├── 源.obj └── 源.obj.enc ├── filesystem.cpp ├── record - 副本.txt ├── record.dat ├── record.txt ├── save.bin ├── tmp.dat ├── user.dat ├── 文件系统.vcxproj ├── 文件系统.vcxproj.filters ├── 文件系统.vcxproj.user └── 源.cpp /.vs/文件系统/v15/.suo: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/szr712/FileSystem/34372149d6dd4a0971acdb4da3cc4d005ad293f7/.vs/文件系统/v15/.suo -------------------------------------------------------------------------------- /.vs/文件系统/v15/Browse.VC.db: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/szr712/FileSystem/34372149d6dd4a0971acdb4da3cc4d005ad293f7/.vs/文件系统/v15/Browse.VC.db -------------------------------------------------------------------------------- /.vs/文件系统/v15/ipch/AutoPCH/7e01b5698d554240/源.ipch: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/szr712/FileSystem/34372149d6dd4a0971acdb4da3cc4d005ad293f7/.vs/文件系统/v15/ipch/AutoPCH/7e01b5698d554240/源.ipch -------------------------------------------------------------------------------- /.vs/文件系统/v15/ipch/AutoPCH/89b2dfd1f3d27413/FILESYSTEM.ipch: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/szr712/FileSystem/34372149d6dd4a0971acdb4da3cc4d005ad293f7/.vs/文件系统/v15/ipch/AutoPCH/89b2dfd1f3d27413/FILESYSTEM.ipch -------------------------------------------------------------------------------- /Debug/文件系统.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/szr712/FileSystem/34372149d6dd4a0971acdb4da3cc4d005ad293f7/Debug/文件系统.exe -------------------------------------------------------------------------------- /Debug/文件系统.ilk: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/szr712/FileSystem/34372149d6dd4a0971acdb4da3cc4d005ad293f7/Debug/文件系统.ilk -------------------------------------------------------------------------------- /Debug/文件系统.pdb: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/szr712/FileSystem/34372149d6dd4a0971acdb4da3cc4d005ad293f7/Debug/文件系统.pdb -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | 2 | # 1.实验要求 3 | 4 | 1. 设计和实现一个模拟文件系统,要求包括目录、普通文件和文件的存储。。 5 | 6 | 2. 文件系统的目录结构采用类似Linux的树状结构。 7 | 8 | 3. 要求模拟的操作包括: 9 | 10 | - 目录的添加、删除、重命名; 11 | 12 | - 目录的显示(列表); 13 | 14 | - 文件的添加、删除、重命名; 15 | 16 | - 文件和目录的拷贝; 17 | 18 | - 文件的读写操作。 19 | 20 | 1. 用户进入时显示可用命令列表;用户输入help时显示所有命令的帮助文档; 21 | 输入某个命令+?时显示该条命令的使用说明。 22 | 23 | 2. 用户输入exit时退出该系统。 24 | 25 | 3. 实验实现基于LINUX平台。 26 | 27 | 4. 实验开发语言必须选用C/C++,不能选用JAVA。 28 | 29 | # 2.实验环境 30 | 31 | - 调试环境: 32 | 33 | - 操作系统:Ubuntu 16.04 TLS; 34 | 35 | - 内存:3.5GiB 36 | 37 | - 处理器:AMD E-350 Processor×2 38 | 39 | - 图形:AMD PALM(DRM 2.50.0/4.15.0-45-generic,LLVM 6.6.6) 40 | 41 | - 操作系统类型:64位 42 | 43 | - 磁盘:30.4GB 44 | 45 | - 开发环境: 46 | 47 | - 开发工具:Visual Studio 2017; 48 | 49 | - 操作系统:Windows 10 家庭中文版; 50 | 51 | - 处理器:Inter(R) Core(TM) i7-8565u CPU \@ 1.8GHz 1.99 GHz; 52 | 53 | - 内存:8.00 GB; 54 | 55 | - 系统类型:64位操作系统,基于x64的处理器。 56 | 57 | # 3.实验设计 58 | 59 | ## 3.1系统流程 60 | 61 | 整体系统操作模拟Ubuntu命令行,具体流程如下: 62 | 63 | ![在这里插入图片描述](https://img-blog.csdnimg.cn/20201016112506877.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3dlaXhpbl80NDMxODE5Mg==,size_16,color_FFFFFF,t_70#pic_center) 64 | 65 | 66 | ## 3.2文件结构 67 | 68 | 整体系统采用属性结构组织文件,具体图示如下: 69 | 70 | ![在这里插入图片描述](https://img-blog.csdnimg.cn/20201016111224166.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3dlaXhpbl80NDMxODE5Mg==,size_16,color_FFFFFF,t_70#pic_center) 71 | 72 | 73 | ## 3.3实现的命令 74 | 75 | 76 | | 命令 | 用法 | 说明 | 选项 | 77 | |--------|---------------------------------|----------------------------------------|------------------------------------------------------------------------------------------------------------| 78 | | cd | cd [dir] | 显示当前目录名或改变当前目录 | 无 | 79 | | ls | ls [dir] | 显示当前或指定路径下所有文件和目录 | 无 | 80 | | mkdir | mkdir dir | 在当前目录下建立一个新目录 | 无 | 81 | | touch | touch file | 在当前目录下新建一个新文件 | 无 | 82 | | gedit | gedit file | 读写指定的文件 | 无 | 83 | | rm | rm -d\|-f file\|dir | 删除指定的目录或文件 | \-d:删除目录 -f:删除文件 | 84 | | cp | cp -d\|-f\|-cd\|-cf SOURSE DEST | 从原路径复制一个文件或目录到目的路径下 | \-d:复制目录 -f:复制文件 -cd:复制目录,但不在原路径下保留原目录 -cf:复制文件,但不在原路径下保留原文件 | 85 | | rename | rename -d\|-f oldname newname | 更改指定文件或目录的名字 | \-d:重命名目录 -f:重命名文件 | 86 | | su | su | 更改当前用户 | 无 | 87 | | cls | cls | 清屏 | 无 | 88 | | exit | exit | 退出文件系统 | 无 | 89 | | help | help | 显示帮助文档 | 无 | 90 | 91 | # 4.数据结构 92 | 93 | 为简化代码结构,系统未采用面向对象编程的思想。将用户、文件、目录分别封装成一个struct结构体。 94 | 95 | ## 4.1 用户数据结构 96 | 97 | ```cpp 98 | struct user 99 | 100 | { 101 | 102 | string name;//用户名 103 | 104 | string password;//密码 105 | 106 | }; 107 | ``` 108 | 109 | 说明:用户结构体中包含用户的用户名以及密码。 110 | 111 | ## 4.2 文件数据结构 112 | 113 | ```cpp 114 | struct file 115 | 116 | { 117 | 118 | string name;//文件名 119 | 120 | vector content;//文件内容 121 | 122 | user owner;//文件所有者 123 | 124 | }; 125 | ``` 126 | 127 | 说明:文件结构体包含文件名、文件内容以及文件所有者。需要特别指出的是,目前系统实现的多用户权限可以概括为:文件创建者为文件所有者,非文件所有者可以知道该文件的存在,但不能对该文件执行读写、复制、删除等操作。 128 | 129 | ## 4.3 目录数据结构 130 | 131 | ```cpp 132 | struct dir { 133 | 134 | string name;//目录名 135 | 136 | dir* pre;//父目录 137 | 138 | map files;//所包含的文件 139 | 140 | map next;//子目录 141 | 142 | }; 143 | ``` 144 | 145 | 说明:目录结构体包含目录名、父目录、当前目录下的文件以及直接子目录。其中,为方便代码编写,后两个成员使用map容器包装,其中map的first为文件名(或目录名),second为对应的文件指针(或目录指针)。 146 | 147 | # 5.模块详解 148 | 149 | ## 5.1 用户指令 150 | 151 | 以下按3.3节展开。 152 | 153 | ### 5.1.1 cd 154 | 155 | - 说明:显示当前目录的绝对路径或改变当前目录。 156 | 157 | - 流程图: 158 | 159 | ![](https://img-blog.csdnimg.cn/20201016111852850.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3dlaXhpbl80NDMxODE5Mg==,size_16,color_FFFFFF,t_70#pic_center) 160 | 161 | 162 | - 关键代码: 163 | 164 | ```cpp 165 | //cd 166 | void cd(string name) { 167 | if (name == "") { 168 | //显示当前目录的绝对路径 169 | } 170 | else { 171 | dir* tmp = pathTrans(name);//解析路径 172 | if (tmp == NULL) { 173 | cout << "No Such Directory.\n"; 174 | } 175 | else { 176 | curdir = tmp;//进入用户输入的路径 177 | } 178 | } 179 | } 180 | ``` 181 | 182 | 183 | ### 5.1.2 ls 184 | 185 | - 说明:显示当前目录下或指定路径下所有文件和目录。 186 | 187 | - 流程图: 188 | 189 | ![在这里插入图片描述](https://img-blog.csdnimg.cn/20201016112055214.png#pic_center) 190 | 191 | 192 | 193 | - 关键代码: 194 | 195 | ```cpp 196 | //ls 197 | void ls(string path) { 198 | dir *tmp = curdir; 199 | if (path != "") { 200 | curdir = pathTrans(path);//解析路径 201 | if (curdir == NULL) { 202 | //输出错误提示 203 | } 204 | } 205 | //遍历输出文件和目录信息 206 | for (auto it = curdir->files.begin(); it != curdir->files.end(); it++) { 207 | } 208 | for (auto it = curdir->next.begin(); it != curdir->next.end(); it++) { 209 | } 210 | curdir = tmp; 211 | } 212 | ``` 213 | 214 | ### 5.1.3 mkdir 215 | 216 | - 说明:在当前目录下建立一个新目录。 217 | 218 | - 用法:mkdir dir,其中dir表示新建目录的目录名。 219 | 220 | - 流程图: 221 | 222 | ![](https://img-blog.csdnimg.cn/20201021134154805.png#pic_center) 223 | 224 | 225 | - 关键代码: 226 | 227 | ```cpp 228 | //创建目录 229 | void mkdir(string name) { 230 | if (name == "") { 231 | cout << "Require Parameters" << endl; 232 | } 233 | else if (curdir->next.find(name) != curdir->next.end()) { 234 | cout << "There is a directory having same name.\n"; 235 | } 236 | else if (!judgeName(name)) { 237 | cout << "Name has at least a illegal character.\n"; 238 | } 239 | else { 240 | dir *tmp = new dir();//一定要这样创建,否则字符串后面就不能读取 241 | tmp->name = name; 242 | tmp->pre = curdir; 243 | curdir->next[name] = tmp; 244 | } 245 | } 246 | ``` 247 | 248 | ### 5.1.4 touch 249 | 250 | - 说明:在当前目录下新建一个新文件。 251 | 252 | - 用法:touch file,其中file表示新建文件的文件名 253 | 254 | - 流程图: 255 | 256 | ![在这里插入图片描述](https://img-blog.csdnimg.cn/20201022174101297.png#pic_center) 257 | 258 | 259 | - 关键代码: 260 | 261 | ```cpp 262 | //建立文件 263 | void touch(string name) { 264 | if (name == "") { 265 | cout << "Require Parameters" << endl; 266 | } 267 | else if (curdir->files.find(name) != curdir->files.end()) { 268 | cout << "There is a same file.\n"; 269 | } 270 | else if (!judgeName(name)) { 271 | cout << "Name has at least a illegal character.\n"; 272 | } 273 | else 274 | { 275 | //建立对应的新文件 276 | } 277 | } 278 | ``` 279 | 280 | 281 | ### 5.1.5 gedit 282 | 283 | - 说明:读写指定的文件。 284 | 285 | - 用法:gedit file,其中file表示需要读写的文件,可以用绝对路径或相对路径指定。 286 | 287 | - 流程图: 288 | 289 | ![在这里插入图片描述](https://img-blog.csdnimg.cn/20201022174122888.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3dlaXhpbl80NDMxODE5Mg==,size_16,color_FFFFFF,t_70#pic_center) 290 | 291 | 292 | 293 | 294 | - 关键代码: 295 | 296 | ```cpp 297 | //编辑文件 298 | void gedit(string name) { 299 | dir *t = curdir; 300 | if (name.find_last_of('/') != name.npos) { 301 | //解析路径 302 | } 303 | //是否存在目标文件 304 | if (curdir->files.find(name) == curdir->files.end()) {} 305 | //目标文件是否为当前用户所拥有 306 | else if (curdir->files[name]->owner.name != curuser.name) {} 307 | else { 308 | ofstream out("tmp.dat"); 309 | //将文件当前内容输入临时文件 310 | for (int i = 0; i < curdir->files[name]->content.size(); i++) {} 311 | out.close(); 312 | //用gedit打开临时文件 313 | system("gedit tmp.dat"); 314 | //读取临时文件中的内容,存入文件 315 | ifstream in("tmp.dat"); 316 | while (getline(in, t)) { 317 | //读取临时文件内容 318 | } 319 | } 320 | curdir = t; 321 | } 322 | ``` 323 | 324 | 325 | - 代码解释: 326 | 327 | 因本文件系统完全运行在内存中,创立的文件与目录并未存在实际磁盘中。因此,为提高用户读写文件的体验,在此引入了一个临时文件机制:将存储在内存中的文件暂时存储到临时文件中,然后用gedit打开这个临时文件。在用户编辑完成后,再将临时文件中的内容转存到内存中。 328 | 329 | Gedit是一个GNOME桌面环境下兼容UTF-8的文本编辑器。它使用GTK+编写而成,因此它十分的简单易用,有良好的语法高亮,对中文支持很好,支持包括gb2312、gbk在内的多种字符编码。 330 | 331 | 虽然这样的操作效率不高,但是借助gedit强大的功能,能给用户带来一种编辑真实文件的体验。 332 | 333 | ### 5.1.6 rm 334 | 335 | - 说明:删除指定的目录或文件。 336 | 337 | - 用法:rm -d\|-f 338 | file\|dir,其中file与dir代表需要删除的文件或目录,目录(或文件)均可用绝对路径或者相对路径表示。 339 | 340 | - 选项: 341 | 342 | - \-d:删除目录; 343 | 344 | - \-f:删除文件。 345 | 346 | - 流程图: 347 | 348 | ![在这里插入图片描述](https://img-blog.csdnimg.cn/20201022174134523.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3dlaXhpbl80NDMxODE5Mg==,size_16,color_FFFFFF,t_70#pic_center) 349 | 350 | 351 | 352 | - 关键代码: 353 | 354 | ```cpp 355 | //删除 356 | void rm(string tmp) { 357 | //选项解析,路径解析 358 | //删除目录 359 | if (option == "-d") { 360 | //是否存在目标目录 361 | if (curdir->next.find(name) == curdir->next.end()) {} 362 | else { 363 | deletedir(curdir->next[name]);//递归删除 364 | } 365 | } 366 | else if (option == "-f") { 367 | //是否存在目标目录 368 | if (curdir->files.find(name) == curdir->files.end()) {} 369 | //是否为文件所有者 370 | else if (curdir->files[name]->owner.name != curuser.name) {} 371 | else { 372 | delete(curdir->files[name]); 373 | } 374 | } 375 | } 376 | 377 | ``` 378 | 379 | - 代码解释:因本系统采用树形的目录结构,因此在删除目录时需要用到递归,如deletedir函数所示。 380 | 381 | ```cpp 382 | //递归删除目录 383 | void deletedir(dir *cur) { 384 | //先删文件 385 | for (auto it = cur->files.begin(); it != cur->files.end(); it++) { 386 | delete(it->second); 387 | } 388 | cur->files.clear(); 389 | //再删目录,要嵌套删除 390 | for (auto it = cur->next.begin(); it != cur->next.end(); it++) { 391 | deletedir(it->second); 392 | } 393 | cur->next.clear(); 394 | delete(cur); 395 | } 396 | 397 | ``` 398 | 399 | ### 5.1.7 cp 400 | 401 | - 说明:复制一个文件或目录到指定路径下。 402 | 403 | - 用法:cp -d\|-f\|-cd\|-cf SOURCE 404 | DEST,其中SOURCE为需要复制的文件或目录,DEST为需要复制到的路径。SOURCE与DEST均可用绝对路径或者相对路径表示。 405 | 406 | - 选项: 407 | 408 | - \-d:复制目录 409 | 410 | - \-f:复制文件 411 | 412 | - \-cd:复制目录,但不在原路径下保留原目录 413 | 414 | - \-cf:复制文件,但不在原路径下保留原文件 415 | 416 | - 流程图: 417 | 418 | ![在这里插入图片描述](https://img-blog.csdnimg.cn/20201022174146208.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3dlaXhpbl80NDMxODE5Mg==,size_16,color_FFFFFF,t_70#pic_center) 419 | 420 | 421 | 422 | - 关键代码: 423 | 424 | ```cpp 425 | //复制 426 | void cp(string tmp) { 427 | //解析选项与路径 428 | 429 | if (option == "-f") { 430 | //是否有同名文件 431 | if (den->files.find(name) != den->files.end()) {} 432 | //是否存在目标文件 433 | else if (sou->files.find(name) == sou->files.end()) {} 434 | //是否为当前用户所拥有 435 | else if (curdir->files[name]->owner.name != curuser.name) {} 436 | else { 437 | file *tmp = new file(*(sou->files[name]));//复制文件 438 | den->files[name] = tmp;//放入目的目录下 439 | } 440 | } 441 | else if (option == "-d") { 442 | //是否有同名目录 443 | if (den->next.find(name) != den->next.end()) {} 444 | //是否存在目标目录 445 | else if (sou->next.find(name) == sou->next.end()) {} 446 | else { 447 | dir *tmp = cpDir(sou->next[name]);//递归复制目录 448 | tmp->pre = den; 449 | den->next[name] = tmp;//放入到目的目录下 450 | } 451 | } 452 | else if (option == "-cf") { 453 | //是否有同名文件 454 | if (den->files.find(name) != den->files.end()){} 455 | //是否存在目标文件 456 | else if (sou->files.find(name) == sou->files.end()){} 457 | //是否为当前用户所拥有 458 | else if (curdir->files[name]->owner.name != curuser.name){} 459 | else 460 | { 461 | den->files[name] = sou->files[name];//放入到目的目录下 462 | sou->files.erase(name); 463 | } 464 | } 465 | 466 | else if (option == "-cd") { 467 | //是否有同名目录 468 | if (den->next.find(name) != den->next.end()){} 469 | //是否存在目标目录 470 | else if (sou->next.find(name) == sou->next.end()){} 471 | else 472 | { 473 | den->next[name] = sou->next[name];//放入到目的目录下 474 | sou->next.erase(name); 475 | } 476 | } 477 | } 478 | 479 | ``` 480 | 481 | - 代码解释:跟删除类似,在复制目录时需要用到递归复制,如cpDir所示。 482 | 483 | ```cpp 484 | //递归复制目录 485 | dir* cpDir(dir *tmp) { 486 | dir *goal = new dir(*tmp); 487 | //清除原来的内容 488 | goal->next.clear(); 489 | goal->files.clear(); 490 | //把文件重建 491 | for (auto it = tmp->files.begin(); it != tmp->files.end(); it++) { 492 | file *f = new file(*(it->second)); 493 | goal->files[it->first] = f; 494 | } 495 | //重建目录 496 | for (auto it = tmp->next.begin(); it != tmp->next.end(); it++) { 497 | dir *d = cpDir(it->second); 498 | d->pre = goal; 499 | goal->next[it->first] = d; 500 | } 501 | return goal; 502 | } 503 | 504 | ``` 505 | 506 | 507 | 508 | ### 5.1.8 rename 509 | 510 | - 说明:更改指定文件或目录的名字。 511 | 512 | - 用法:rename -d\|-f oldname 513 | newname,oldname代表需要重命名的目录或文件,newname代表重命名后的名字。oldname可以使用绝对路径或相对路径。 514 | 515 | - 选项: 516 | 517 | - \-d:重命名目录; 518 | 519 | - \-f:重命名文件。 520 | 521 | - 流程图: 522 | 523 | ![在这里插入图片描述](https://img-blog.csdnimg.cn/20201022174201976.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3dlaXhpbl80NDMxODE5Mg==,size_16,color_FFFFFF,t_70#pic_center) 524 | 525 | 526 | 527 | - 关键代码: 528 | 529 | ```cpp 530 | void rename(string tmp) { 531 | //解析路径与选项 532 | 533 | if (!judgeName(newname)) {}//新名字中是否有非法字符 534 | if (option == "-d") { 535 | if (curdir->next.find(old) == curdir->next.end()) {}//是否存在目标目录 536 | else if (curdir->next.find(newname) != curdir->next.end()) {}//是否存在与新名字重名的目录 537 | else { 538 | //重命名 539 | } 540 | } 541 | else if (option == "-f") { 542 | if (curdir->files.find(old) == curdir->files.end()) {}//是否存在对应文件 543 | else if (curdir->files.find(newname) != curdir->files.end()) {}//是否存在与新名字重名的文件 544 | else if (curdir->files[old]->owner.name != curuser.name) {}//需重命名文件是否为当前用户拥有 545 | else { 546 | //重命名 547 | } 548 | } 549 | } 550 | 551 | ``` 552 | 553 | ### 5.1.9 su 554 | 555 | - 说明:更改当前用户(调用login函数,详见下文)。 556 | 557 | ### 5.1.10 cls 558 | 559 | - 说明:清屏。 560 | 561 | ### 5.1.11 exit 562 | 563 | - 说明:退出文件系统(主要调用save函数,详见下文)。 564 | 565 | ### 5.1.12 help 566 | 567 | - 说明:显示帮助文档。 568 | 569 | ## 5.2 其他系统操作 570 | 571 | ### 5.2.1 登录 572 | 573 | - 流程图: 574 | ![在这里插入图片描述](https://img-blog.csdnimg.cn/20201022174213369.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3dlaXhpbl80NDMxODE5Mg==,size_16,color_FFFFFF,t_70#pic_center) 575 | 576 | 577 | 578 | - 关键代码: 579 | 580 | ```cpp 581 | void login() { 582 | bool flag = 1; 583 | map users;//所有注册用户 584 | //打印欢迎语 585 | 586 | ifstream in("user.dat"); 587 | string tname, tpass; 588 | while (in >> tname >> tpass) {}//读入所有注册用户的信息 589 | //输入用户名 590 | 591 | while (flag) { 592 | if (users.find(tname) == users.end()) {}//注册用户中是否有输入用户 593 | else { 594 | if (users[tname] == tpass) { 595 | //核对用户名与密码是否匹配 596 | } 597 | else { 598 | printf("password is incorrect!\n"); 599 | } 600 | } 601 | } 602 | if (!flag) { 603 | printf("This user is not exist.\nDo you want to creat a new user?(y/n):"); 604 | char choice; 605 | cin >> choice; 606 | if (choice == 'Y' || choice == 'y') { 607 | //注册 608 | } 609 | else { 610 | login(); 611 | } 612 | } 613 | //重新存回 614 | ofstream out("user.dat"); 615 | for (auto it = users.begin(); it != users.end(); it++) {} 616 | return; 617 | } 618 | ``` 619 | 620 | ### 5.2.2 保存系统状态 621 | 622 | 为提高用户体验,每次用户使用exit命令退出系统时,系统会保存退出前的系统状态。 623 | 624 | 保存系统状态的主要实现思想是:通过递归遍历系统的目录结构,以字符串向量的形式存储包括目录名、文件名、文件内容在内的所有信息。最后将字符串向量存入record.dat文件。字符串向量内部的结构类似xml文件。具体流程图与代码如下: 625 | 626 | - 流程图: 627 | 628 | - exit函数: 629 | 630 | ![在这里插入图片描述](https://img-blog.csdnimg.cn/202010221742443.png#pic_center) 631 | 632 | 633 | 634 | - save函数: 635 | 636 | ![在这里插入图片描述](https://img-blog.csdnimg.cn/20201022174250555.png#pic_center) 637 | 638 | 639 | 640 | - 具体代码: 641 | ```cpp 642 | //退出系统 643 | void exit() { 644 | records.clear(); 645 | save(root); 646 | ofstream outr("record.dat"); 647 | for (int i = 0; i < records.size(); i++) { 648 | outr << records[i] << endl; 649 | } 650 | } 651 | ``` 652 | ```cpp 653 | //存储目前情况 654 | void save(dir *tmp) { 655 | records.push_back(tmp->name);//目录名 656 | records.push_back(to_string(tmp->files.size()));//文件数 657 | for (auto it = tmp->files.begin(); it != tmp->files.end(); it++) { 658 | records.push_back(it->second->name);//文件名 659 | for (int i = 0; i < it->second->content.size(); i++) { 660 | records.push_back( it->second->content[i]);//文件内容 661 | } 662 | records.push_back("content");//文件内容结束符 663 | records.push_back(it->second->owner.name);//所有者用户名 664 | records.push_back(it->second->owner.password);//所有者密码 665 | } 666 | records.push_back(to_string(tmp->next.size()));//子目录数 667 | for (auto it = tmp->next.begin(); it != tmp->next.end(); it++) { 668 | records.push_back(it->second->name);//子目录名 669 | save(it->second);//递归子目录 670 | } 671 | } 672 | 673 | ``` 674 | 675 | 676 | 为方便调试,record.dat文件以明文存储,文件内容如下: 677 | 678 | ![在这里插入图片描述](https://img-blog.csdnimg.cn/20201022174310507.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3dlaXhpbl80NDMxODE5Mg==,size_16,color_FFFFFF,t_70#pic_center) 679 | 680 | 681 | 682 | ### 5.2.3 恢复系统状态 683 | 684 | 为提高用户体验,每次打开系统时,系统会根据record.dat文件存储的系统状态恢复上一次退出前的系统状态。 685 | 686 | 恢复系统状态的实现思想与保存系统状态(5.2.2)类似,根据record.dat的数据重建目录结构。 687 | 具体流程图与代码如下: 688 | 689 | - 流程图: 690 | 691 | - init函数: 692 | 693 | ![在这里插入图片描述](https://img-blog.csdnimg.cn/20201022174317526.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3dlaXhpbl80NDMxODE5Mg==,size_16,color_FFFFFF,t_70#pic_center) 694 | 695 | 696 | - creat函数: 697 | 698 | ![在这里插入图片描述](https://img-blog.csdnimg.cn/20201022174324907.png#pic_center) 699 | 700 | 701 | - 具体代码: 702 | 703 | ```cpp 704 | void init() { 705 | ifstream inr("record.dat"); 706 | string tmp; 707 | if (!inr) { 708 | initDir(); 709 | } 710 | while (inr >> tmp) 711 | records.push_back(tmp); 712 | if (records.size() >= 1) { 713 | root = curdir = creat(NULL); 714 | } 715 | else { 716 | initDir(); 717 | } 718 | } 719 | ``` 720 | ```cpp 721 | //还原上一次系统关闭状态 722 | dir* creat(dir *last) { 723 | dir *tmp = new dir();//新建目录 724 | tmp->name=records[reco++];//读取目录名 725 | tmp->pre = last;//设置父指针 726 | string t; 727 | t= records[reco++];//读取文件数 728 | for (int i = 0; i < stoi(t); i++) { 729 | file *tfile = new file();//新建文件 730 | tfile->name= records[reco++];//读取文件名 731 | while (1) { 732 | string ts; 733 | ts= records[reco++];//读取文件内容 734 | if (ts != "content") {//不是关键字就持续读入内容 735 | tfile->content.push_back(ts); 736 | } 737 | else { 738 | break; 739 | } 740 | } 741 | user a; 742 | a.name = records[reco++];//读取用户名 743 | a.password= records[reco++];//密码 744 | tfile->owner = a; 745 | tmp->files[tfile->name] = tfile;//将新建的文件加入目录 746 | } 747 | t= records[reco++];//子目录数 748 | for (int i = 0; i < stoi(t); i++) { 749 | string name; 750 | name= records[reco++];//子目录名 751 | tmp->next[name] = creat(tmp);//递归新建子目录 752 | } 753 | return tmp; 754 | } 755 | ``` 756 | 757 | ### 5.2.4 路径解析 758 | 759 | 为提高用户体验,系统引入了路径解析的机制,可以让包括cd、ls、gedit在内的多种操作同时支持相对路径与绝对路径。绝对路径与相对路径的表示方式与Ubuntu系统相同。 760 | 761 | 路径解析输入的参数为绝对路径或相对路径,返回的结果是目标目录的指针。具体流程图与代码如下: 762 | 763 | - 流程图: 764 | 765 | ![在这里插入图片描述](https://img-blog.csdnimg.cn/20201022174350812.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3dlaXhpbl80NDMxODE5Mg==,size_16,color_FFFFFF,t_70#pic_center) 766 | 767 | - 关键代码: 768 | 769 | ```cpp 770 | dir* pathTrans(string path) { 771 | string tmp = path; 772 | //绝对路径 773 | if (path[0] == '~' || path[0] == '/') { 774 | dir *cur = root; 775 | if (path[0] == '/')path = "~" + path; 776 | vector tmp = split(path);//按照/分割路径 777 | for (int i = 1; i < tmp.size(); i++) { 778 | if (cur->next.find(tmp[i]) == cur->next.end()) { 779 | return NULL; 780 | } 781 | cur = cur->next[tmp[i]]; 782 | } 783 | return cur; 784 | } 785 | //相对路径 786 | else { 787 | dir *cur = curdir; 788 | vector tmp = split(path);//按照/分割路径 789 | for (int i = 0; i < tmp.size(); i++) { 790 | if (tmp[i] == ".") { 791 | 792 | } 793 | else if (tmp[i] == "..") { 794 | if (cur == root) {//不能再往上走了 795 | return NULL; 796 | } 797 | else { 798 | cur = cur->pre; 799 | } 800 | } 801 | else if (cur->next.find(tmp[i]) == cur->next.end()) { 802 | return NULL; 803 | } 804 | else if (cur->next.find(tmp[i]) != cur->next.end()) { 805 | cur = cur->next[tmp[i]]; 806 | } 807 | } 808 | return cur; 809 | } 810 | return NULL; 811 | } 812 | ``` 813 | 814 | # 6.实验演示 815 | 816 | ## 6.1登录 817 | 818 | - 欢迎界面 819 | 820 | ![在这里插入图片描述](https://img-blog.csdnimg.cn/20201022174516365.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3dlaXhpbl80NDMxODE5Mg==,size_16,color_FFFFFF,t_70#pic_center) 821 | 822 | 823 | - 当用户名与密码不匹配,系统会让用户反复输入密码,直到正确为止: 824 | 825 | ![在这里插入图片描述](https://img-blog.csdnimg.cn/20201022174610430.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3dlaXhpbl80NDMxODE5Mg==,size_16,color_FFFFFF,t_70#pic_center) 826 | 827 | 828 | 829 | - 当输入用户名与不在已注册用户中,若用户同意创建用户,系统会根据先前输入的用户名与密码创建用户: 830 | 831 | ![在这里插入图片描述](https://img-blog.csdnimg.cn/20201022174636103.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3dlaXhpbl80NDMxODE5Mg==,size_16,color_FFFFFF,t_70#pic_center) 832 | 833 | 834 | 835 | ## 6.2帮助文档与使用说明 836 | 837 | - 用户输入help时显示所有命令的帮助文档: 838 | 839 | ![在这里插入图片描述](https://img-blog.csdnimg.cn/20201022174643946.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3dlaXhpbl80NDMxODE5Mg==,size_16,color_FFFFFF,t_70#pic_center) 840 | 841 | 842 | - 输入某个命令+?时显示该条命令的使用说明: 843 | 844 | ![在这里插入图片描述](https://img-blog.csdnimg.cn/20201022174659624.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3dlaXhpbl80NDMxODE5Mg==,size_16,color_FFFFFF,t_70#pic_center) 845 | 846 | 847 | 848 | ## 6.3 cd命令 849 | ![在这里插入图片描述](https://img-blog.csdnimg.cn/20201022174708643.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3dlaXhpbl80NDMxODE5Mg==,size_16,color_FFFFFF,t_70#pic_center) 850 | 851 | 852 | 853 | 说明:红框为目前根节点下拥有的目录;黄框展示使用相对路径、绝对路径更改目录,以及回到上一级目录的情况;蓝框展示遇到错误路径的情况。 854 | 855 | ## 6.4 ls命令 856 | 857 | ![在这里插入图片描述](https://img-blog.csdnimg.cn/2020102217471766.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3dlaXhpbl80NDMxODE5Mg==,size_16,color_FFFFFF,t_70#pic_center) 858 | 859 | 860 | 说明:黄框展示有参及无参ls命令的使用情况;蓝框展示遇到错误路径的情况。 861 | 862 | ## 6.5 mkdir命令 863 | 864 | ![在这里插入图片描述](https://img-blog.csdnimg.cn/20201022174725761.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3dlaXhpbl80NDMxODE5Mg==,size_16,color_FFFFFF,t_70#pic_center) 865 | ![在这里插入图片描述](https://img-blog.csdnimg.cn/20201022174733122.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3dlaXhpbl80NDMxODE5Mg==,size_16,color_FFFFFF,t_70#pic_center) 866 | 867 | ![在这里插入图片描述](https://img-blog.csdnimg.cn/20201022174742918.png#pic_center) 868 | 869 | 870 | 871 | 说明:红框展示目前根节点下拥有的目录;黄框展示新建一个paly目录的情况;蓝框展示遇到重名目录的情况;第三张图展示新建目录名中存在非法字符的情况。 872 | 873 | ## 6.6 touch命令 874 | 875 | ![在这里插入图片描述](https://img-blog.csdnimg.cn/20201022174823428.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3dlaXhpbl80NDMxODE5Mg==,size_16,color_FFFFFF,t_70#pic_center) 876 | 877 | 878 | 879 | 说明:红框展示\~/study/college目录下拥有的文件;黄框展示新建一个test2.txt文件的情况;蓝框展示遇到重名文件的情况;展示新建文件名中存在非法字符的情况。 880 | 881 | ## 6.7 gedit命令 882 | 883 | ![在这里插入图片描述](https://img-blog.csdnimg.cn/20201022174845852.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3dlaXhpbl80NDMxODE5Mg==,size_16,color_FFFFFF,t_70#pic_center) 884 | 885 | 886 | 887 | 说明:红框展示\~/study/college目录下拥有的文件;黄框展示读写test2.txt文件的情况,截图下半部为gedit打开临时文件;蓝框展示遇到缺少文件名及文件非当前用户拥有的情况。 888 | 889 | ## 6.8 rm命令 890 | 891 | ![在这里插入图片描述](https://img-blog.csdnimg.cn/20201022174856914.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3dlaXhpbl80NDMxODE5Mg==,size_16,color_FFFFFF,t_70#pic_center) 892 | 893 | 894 | 说明:红框展示根目录下拥有的文件与目录;黄框展示删除work目录的情况;绿框展示删除test.txt文件的情况;蓝框展示遇到不存在目录或文件的情况。 895 | 896 | ## 6.9 cp命令 897 | ![在这里插入图片描述](https://img-blog.csdnimg.cn/20201022174932863.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3dlaXhpbl80NDMxODE5Mg==,size_16,color_FFFFFF,t_70#pic_center) 898 | 899 | 900 | 说明:红框展示\~/study目录与\~/work目录下拥有的文件与目录;黄框展示复制college目录到\~/work目录的情况。 901 | 902 | ![](https://img-blog.csdnimg.cn/20201022174939527.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3dlaXhpbl80NDMxODE5Mg==,size_16,color_FFFFFF,t_70#pic_center) 903 | 904 | 905 | 906 | 说明:红框展示\~/work与\~/study/college目录下拥有的文件与目录;黄框展示复制test2.txt文件到\~/work目录的情况。 907 | 908 | ![在这里插入图片描述](https://img-blog.csdnimg.cn/2020102217510360.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3dlaXhpbl80NDMxODE5Mg==,size_16,color_FFFFFF,t_70#pic_center) 909 | 910 | 911 | 912 | 913 | 说明:红框展示\~/work与\~/study/college目录下拥有的文件与目录;黄框展示剪贴test2.txt文件到\~/work目录的情况。 914 | 915 | ![](https://img-blog.csdnimg.cn/20201022174949589.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3dlaXhpbl80NDMxODE5Mg==,size_16,color_FFFFFF,t_70#pic_center) 916 | 917 | 918 | 说明:红框展示\~/work与\~/study目录下拥有的文件与目录;黄框展示剪贴college目录到\~/work目录的情况。 919 | 920 | ## 6.10 用户权限 921 | 922 | 系统实现的多用户权限可以概括为:文件创建者为文件所有者,非文件所有者可以知道该文件的存在,但不能对该文件执行读写、复制、删除等操作。下图展示了非文件所有者不能对文件执行gedit、rm、rename、cp命令的情况: 923 | 924 | ![在这里插入图片描述](https://img-blog.csdnimg.cn/202010221751176.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3dlaXhpbl80NDMxODE5Mg==,size_16,color_FFFFFF,t_70#pic_center) 925 | 926 | -------------------------------------------------------------------------------- /文件系统.sln: -------------------------------------------------------------------------------- 1 |  2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio 15 4 | VisualStudioVersion = 15.0.28307.902 5 | MinimumVisualStudioVersion = 10.0.40219.1 6 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "文件系统", "文件系统\文件系统.vcxproj", "{D0B0D89A-3A53-49AC-AA3A-A3F48139AEBD}" 7 | EndProject 8 | Global 9 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 10 | Debug|x64 = Debug|x64 11 | Debug|x86 = Debug|x86 12 | Release|x64 = Release|x64 13 | Release|x86 = Release|x86 14 | EndGlobalSection 15 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 16 | {D0B0D89A-3A53-49AC-AA3A-A3F48139AEBD}.Debug|x64.ActiveCfg = Debug|x64 17 | {D0B0D89A-3A53-49AC-AA3A-A3F48139AEBD}.Debug|x64.Build.0 = Debug|x64 18 | {D0B0D89A-3A53-49AC-AA3A-A3F48139AEBD}.Debug|x86.ActiveCfg = Debug|Win32 19 | {D0B0D89A-3A53-49AC-AA3A-A3F48139AEBD}.Debug|x86.Build.0 = Debug|Win32 20 | {D0B0D89A-3A53-49AC-AA3A-A3F48139AEBD}.Release|x64.ActiveCfg = Release|x64 21 | {D0B0D89A-3A53-49AC-AA3A-A3F48139AEBD}.Release|x64.Build.0 = Release|x64 22 | {D0B0D89A-3A53-49AC-AA3A-A3F48139AEBD}.Release|x86.ActiveCfg = Release|Win32 23 | {D0B0D89A-3A53-49AC-AA3A-A3F48139AEBD}.Release|x86.Build.0 = Release|Win32 24 | EndGlobalSection 25 | GlobalSection(SolutionProperties) = preSolution 26 | HideSolutionNode = FALSE 27 | EndGlobalSection 28 | GlobalSection(ExtensibilityGlobals) = postSolution 29 | SolutionGuid = {40BAD1DB-B34D-4063-BFB5-0A6E21B7D86F} 30 | EndGlobalSection 31 | EndGlobal 32 | -------------------------------------------------------------------------------- /文件系统/Debug/vc141.idb: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/szr712/FileSystem/34372149d6dd4a0971acdb4da3cc4d005ad293f7/文件系统/Debug/vc141.idb -------------------------------------------------------------------------------- /文件系统/Debug/vc141.pdb: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/szr712/FileSystem/34372149d6dd4a0971acdb4da3cc4d005ad293f7/文件系统/Debug/vc141.pdb -------------------------------------------------------------------------------- /文件系统/Debug/文件系统.log: -------------------------------------------------------------------------------- 1 |  源.cpp 2 | d:\study\大三上\操作系统原理\实验\课程设计\文件系统\文件系统\源.cpp(72): warning C4018: “<”: 有符号/无符号不匹配 3 | d:\study\大三上\操作系统原理\实验\课程设计\文件系统\文件系统\源.cpp(92): warning C4018: “<”: 有符号/无符号不匹配 4 | d:\study\大三上\操作系统原理\实验\课程设计\文件系统\文件系统\源.cpp(104): warning C4018: “<”: 有符号/无符号不匹配 5 | d:\study\大三上\操作系统原理\实验\课程设计\文件系统\文件系统\源.cpp(342): warning C4018: “<”: 有符号/无符号不匹配 6 | d:\study\大三上\操作系统原理\实验\课程设计\文件系统\文件系统\源.cpp(652): warning C4018: “<”: 有符号/无符号不匹配 7 | d:\study\大三上\操作系统原理\实验\课程设计\文件系统\文件系统\源.cpp(723): warning C4018: “<”: 有符号/无符号不匹配 8 | 文件系统.vcxproj -> D:\study\大三上\操作系统原理\实验\课程设计\文件系统\Debug\文件系统.exe 9 | -------------------------------------------------------------------------------- /文件系统/Debug/文件系统.tlog/CL.command.1.tlog: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/szr712/FileSystem/34372149d6dd4a0971acdb4da3cc4d005ad293f7/文件系统/Debug/文件系统.tlog/CL.command.1.tlog -------------------------------------------------------------------------------- /文件系统/Debug/文件系统.tlog/CL.read.1.tlog: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/szr712/FileSystem/34372149d6dd4a0971acdb4da3cc4d005ad293f7/文件系统/Debug/文件系统.tlog/CL.read.1.tlog -------------------------------------------------------------------------------- /文件系统/Debug/文件系统.tlog/CL.write.1.tlog: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/szr712/FileSystem/34372149d6dd4a0971acdb4da3cc4d005ad293f7/文件系统/Debug/文件系统.tlog/CL.write.1.tlog -------------------------------------------------------------------------------- /文件系统/Debug/文件系统.tlog/link.command.1.tlog: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/szr712/FileSystem/34372149d6dd4a0971acdb4da3cc4d005ad293f7/文件系统/Debug/文件系统.tlog/link.command.1.tlog -------------------------------------------------------------------------------- /文件系统/Debug/文件系统.tlog/link.read.1.tlog: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/szr712/FileSystem/34372149d6dd4a0971acdb4da3cc4d005ad293f7/文件系统/Debug/文件系统.tlog/link.read.1.tlog -------------------------------------------------------------------------------- /文件系统/Debug/文件系统.tlog/link.write.1.tlog: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/szr712/FileSystem/34372149d6dd4a0971acdb4da3cc4d005ad293f7/文件系统/Debug/文件系统.tlog/link.write.1.tlog -------------------------------------------------------------------------------- /文件系统/Debug/文件系统.tlog/文件系统.lastbuildstate: -------------------------------------------------------------------------------- 1 | #TargetFrameworkVersion=v4.0:PlatformToolSet=v141:EnableManagedIncrementalBuild=false:VCToolArchitecture=Native32Bit:WindowsTargetPlatformVersion=10.0.17763.0 2 | Debug|Win32|D:\study\大三上\操作系统原理\实验\课程设计\文件系统\| 3 | -------------------------------------------------------------------------------- /文件系统/Debug/源.obj: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/szr712/FileSystem/34372149d6dd4a0971acdb4da3cc4d005ad293f7/文件系统/Debug/源.obj -------------------------------------------------------------------------------- /文件系统/Debug/源.obj.enc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/szr712/FileSystem/34372149d6dd4a0971acdb4da3cc4d005ad293f7/文件系统/Debug/源.obj.enc -------------------------------------------------------------------------------- /文件系统/filesystem.cpp: -------------------------------------------------------------------------------- 1 | //+?的说明还没写 错误字符 cd的路径 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include 12 | #include 13 | //#include 14 | #include 15 | #include 16 | using namespace std; 17 | 18 | 19 | 20 | vector records; 21 | int reco = 0; 22 | 23 | struct user 24 | { 25 | string name;//用户名 26 | string password;//密码 27 | }; 28 | 29 | struct file 30 | { 31 | string name;//文件名 32 | vector content;//文件内容 33 | user owner;//文件所有者 34 | }; 35 | 36 | struct dir { 37 | string name;//目录名 38 | dir* pre;//父目录 39 | map files;//所包含的文件 40 | map next;//子目录 41 | }; 42 | 43 | user curuser;//当前用户 44 | dir* curdir;//当前目录 45 | dir* root;//根目录 46 | 47 | void initDir() { 48 | curdir = new dir(); 49 | curdir->name = "~"; 50 | curdir->pre = NULL; 51 | root = curdir; 52 | } 53 | 54 | void displayPath() { 55 | dir* tmp = curdir; 56 | vector path; 57 | while (tmp != NULL) { 58 | path.push_back(tmp->name); 59 | tmp = tmp->pre; 60 | } 61 | cout << "~"; 62 | for (int i = path.size() - 2; i >= 0; i--) { 63 | cout << "/" << path[i]; 64 | } 65 | cout << "$ "; 66 | } 67 | 68 | //按照‘/’拆分字符串 69 | vector split(string str) { 70 | vector ans; 71 | string tmp = ""; 72 | for (int i = 0; i < str.length(); i++) { 73 | if (str[i] != '/') { 74 | tmp = tmp + str[i]; 75 | } 76 | else { 77 | ans.push_back(tmp); 78 | tmp = ""; 79 | } 80 | } 81 | if (tmp != "")ans.push_back(tmp); 82 | return ans; 83 | } 84 | 85 | dir* pathTrans(string path) { 86 | string tmp = path; 87 | //绝对路径 88 | if (path[0] == '~' || path[0] == '/') { 89 | dir *cur = root; 90 | if (path[0] == '/')path = "~" + path; 91 | vector tmp = split(path); 92 | for (int i = 1; i < tmp.size(); i++) { 93 | if (cur->next.find(tmp[i]) == cur->next.end()) { 94 | return NULL; 95 | } 96 | cur = cur->next[tmp[i]]; 97 | } 98 | return cur; 99 | } 100 | //相对路径 101 | else { 102 | dir *cur = curdir; 103 | vector tmp = split(path); 104 | for (int i = 0; i < tmp.size(); i++) { 105 | if (tmp[i] == ".") { 106 | 107 | } 108 | else if (tmp[i] == "..") { 109 | if (cur == root) {//不能再往上走了 110 | return NULL; 111 | } 112 | else { 113 | cur = cur->pre; 114 | } 115 | } 116 | else if (cur->next.find(tmp[i]) == cur->next.end()) { 117 | return NULL; 118 | } 119 | else if (cur->next.find(tmp[i]) != cur->next.end()) { 120 | cur = cur->next[tmp[i]]; 121 | } 122 | } 123 | return cur; 124 | } 125 | return NULL; 126 | } 127 | 128 | bool judgeName(string name) { 129 | if (name.find("\\") != name.npos || name.find("/") != name.npos || name.find(":") != name.npos || name.find("*") != name.npos || name.find("?") != name.npos 130 | || name.find("<") != name.npos || name.find(">") != name.npos || name.find("|") != name.npos || name.find("\"") != name.npos || name.find("..") != name.npos || name.find(" ") != name.npos) return false; 131 | return true; 132 | } 133 | 134 | void login() { 135 | bool flag = 1; 136 | map users; 137 | system("cls"); 138 | cout << "\n\n\n"; 139 | cout << "\t\t 操作系统课程设计-模拟文件系统" << endl << endl << endl << endl << endl << endl; 140 | cout << "\t\t 作者:邵子睿" << endl << endl << endl; 141 | ifstream in("user.dat"); 142 | if (!in) { 143 | cout << "打开文件出错!即将退出!" << endl; 144 | system("Pause"); 145 | exit(1); 146 | } 147 | string tname, tpass; 148 | while (in >> tname >> tpass) { 149 | users[tname] = tpass; 150 | } 151 | printf("username:"); 152 | cin >> tname; 153 | while (flag) { 154 | 155 | printf("password:"); 156 | cin >> tpass; 157 | if (users.find(tname) == users.end()) { 158 | flag = 0; 159 | } 160 | else { 161 | if (users[tname] == tpass) { 162 | system("cls"); 163 | curuser.name = tname; 164 | curuser.password = tpass; 165 | break; 166 | } 167 | else { 168 | printf("password is incorrect!\n"); 169 | } 170 | } 171 | } 172 | if (!flag) { 173 | printf("This user is not exist.\nDo you want to creat a new user?(y/n):"); 174 | char choice; 175 | cin >> choice; 176 | if (choice == 'Y' || choice == 'y') { 177 | users[tname] = tpass; 178 | curuser.name = tname; 179 | curuser.password = tpass; 180 | system("cls"); 181 | } 182 | else { 183 | login(); 184 | } 185 | } 186 | //重新存回 187 | ofstream out("user.dat"); 188 | for (auto it = users.begin(); it != users.end(); it++) { 189 | out << it->first << " " << it->second << endl; 190 | } 191 | getchar(); 192 | return; 193 | } 194 | 195 | void help() { 196 | printf("command: \n\ 197 | help --- show help menu \n\ 198 | cd --- change the shell working directory \n\ 199 | cls --- clear the screen \n\ 200 | ls --- show all the files and directories in particular directory \n\ 201 | mkdir --- create the directory,if it does not already exist. \n\ 202 | touch --- create a new file \n\ 203 | gedit --- read and write something to a particular file \n\ 204 | rm --- delete a exist file or a directory\n\ 205 | cp --- copy SOURSE to DEST \n\ 206 | rename --- rename a exist file or a directory \n\ 207 | su --- switch current user \n\ 208 | exit --- exit this system \n"); 209 | } 210 | 211 | void help2(string command) { 212 | if (command == "cd?") printf("cd: cd [dir]\nchange the shell working directory.\n"); 213 | else if (command == "ls?")printf("ls: ls [dir]\nShow all the files and directories in particular directory.\n"); 214 | else if (command == "mkdir?") printf("mkdir: mkdir dir\nCreate the directory,if it does not already exist.\n"); 215 | else if (command == "touch?")printf("touch: touch file\nCreate a new file,if it does not already exist.\n"); 216 | else if (command == "gedit?")printf("gedit: gedit file\nRead and write something to a particular file.\n"); 217 | else if (command == "rm?")printf("rm: rm -d|-f file|dir\nDelete a exist file or a directory.\noption:\n-d:delete a directory\n-f:delete a file\n"); 218 | else if (command == "cp?")printf("cp: cp -d|-f|-cd|-cf SOURSE DEST\nCopy SOURSE to DEST\noption:\n-d:copy a directory\n-f:copy a file\n-cd:cut a directory\n-cf:cut a file\n"); 219 | else if (command == "rename?")printf("rename: rename -d|-f oldname newname\nRename a exist file or a directory.\noption:\n-d:rename a directory\n-f:rename a file\n"); 220 | else if (command == "su?")printf("Switch current user.\n"); 221 | else if (command == "cls?")printf("Clear the screen.\n"); 222 | else if (command == "exit?")printf("Exit this system.\n"); 223 | else printf("Wrong Command!\n"); 224 | 225 | } 226 | 227 | //创建目录 228 | void mkdir(string name) { 229 | if (name == "") { 230 | cout << "Require Parameters" << endl; 231 | } 232 | else if (curdir->next.find(name) != curdir->next.end()) { 233 | cout << "There is a directory having same name.\n"; 234 | } 235 | else if (!judgeName(name)) { 236 | cout << "Name has at least a illegal character.\n"; 237 | } 238 | else { 239 | dir *tmp = new dir();//一定要这样创建,否则字符串后面就不能读取 240 | tmp->name = name; 241 | tmp->pre = curdir; 242 | curdir->next[name] = tmp; 243 | } 244 | } 245 | 246 | //cd 247 | void cd(string name) { 248 | if (name == "") { 249 | dir* tmp = curdir; 250 | vector path; 251 | while (tmp != NULL) { 252 | path.push_back(tmp->name); 253 | tmp = tmp->pre; 254 | } 255 | cout << "~"; 256 | for (int i = path.size() - 2; i >= 0; i--) { 257 | cout << "/" << path[i]; 258 | } 259 | cout << endl; 260 | } 261 | else { 262 | dir* tmp = pathTrans(name); 263 | if (tmp == NULL) { 264 | cout << "No Such Directory.\n"; 265 | } 266 | else { 267 | curdir = tmp; 268 | } 269 | } 270 | } 271 | 272 | //建立文件 273 | void touch(string name) { 274 | //string name;//文件名 275 | //cin >> name; 276 | if (name == "") { 277 | cout << "Require Parameters" << endl; 278 | } 279 | else if (curdir->files.find(name) != curdir->files.end()) { 280 | cout << "There is a same file.\n"; 281 | } 282 | else if (!judgeName(name)) { 283 | cout << "Name has at least a illegal character.\n"; 284 | } 285 | else 286 | { 287 | file *tmp = new file(); 288 | tmp->name = name; 289 | tmp->owner = curuser; 290 | tmp->content.push_back(""); 291 | curdir->files[name] = tmp; 292 | } 293 | } 294 | 295 | //ls 296 | void ls(string path) { 297 | dir *tmp = curdir; 298 | if (path != "") { 299 | curdir = pathTrans(path); 300 | if (curdir == NULL) { 301 | curdir = tmp; 302 | printf("Wrong Path!\n"); 303 | return; 304 | } 305 | } 306 | for (auto it = curdir->files.begin(); it != curdir->files.end(); it++) { 307 | cout << it->first << setw(25 - it->first.length()) << "" << " owner:" << it->second->owner.name << endl; 308 | } 309 | for (auto it = curdir->next.begin(); it != curdir->next.end(); it++) { 310 | cout << it->first << setw(26 - it->first.length()) << " " << endl; 311 | } 312 | curdir = tmp; 313 | } 314 | 315 | //编辑文件 316 | void gedit(string name) { 317 | dir *t = curdir; 318 | if (name == "") { 319 | cout << "Require Parameters" << endl; 320 | return; 321 | } 322 | else if (name.find_last_of('/') != name.npos) { 323 | string tmp = name; 324 | if (tmp[0] == '/') tmp = "~" + tmp; 325 | tmp = tmp.substr(0, tmp.find_last_of('/')); 326 | name = name.substr(name.find_last_of('/') + 1, name.length() - name.find_last_of('/')); 327 | curdir = pathTrans(tmp); 328 | if (curdir == NULL) { 329 | curdir = t; 330 | printf("Wrong Path!\n"); 331 | return; 332 | } 333 | } 334 | if (curdir->files.find(name) == curdir->files.end()) { 335 | cout << "No Such File.\n"; 336 | } 337 | else if (curdir->files[name]->owner.name != curuser.name) { 338 | cout << "This file is not yours!\n"; 339 | } 340 | else { 341 | ofstream out("tmp.dat"); 342 | for (int i = 0; i < curdir->files[name]->content.size(); i++) { 343 | out << curdir->files[name]->content[i] << endl; 344 | } 345 | out.close(); 346 | system("notepad tmp.dat"); 347 | ifstream in("tmp.dat"); 348 | string t; 349 | curdir->files[name]->content.clear();//清除原来数组内的内容 350 | while (getline(in, t)) { 351 | curdir->files[name]->content.push_back(t); 352 | } 353 | } 354 | curdir = t; 355 | } 356 | 357 | //重命名 358 | void rename(string tmp) { 359 | dir *t = curdir; 360 | string option = ""; 361 | if (tmp.find_first_of('-') != tmp.npos&&tmp.length() >= 2) { 362 | option = tmp.substr(tmp.find_first_of('-'), 2); 363 | } 364 | else { 365 | cout << "Wrong Option!\n"; 366 | return; 367 | } 368 | string old = "", newname = ""; 369 | old = tmp.substr(tmp.find_first_of('-') + 3, tmp.find_last_of(' ') - tmp.find_first_of('-') - 3); 370 | newname = tmp.substr(tmp.find_last_of(' ') + 1, tmp.length() - tmp.find_last_of(' ')); 371 | if (!judgeName(newname)) { 372 | cout << "Newname has at least a illegal character.\n"; 373 | return; 374 | } 375 | if (newname == "" || old == "" || newname == old) { 376 | cout << "Require Parameters" << endl; 377 | return; 378 | } 379 | if (old.find_last_of('/') != old.npos) { 380 | string tmp = old; 381 | if (tmp[0] == '/') tmp = "~" + tmp; 382 | tmp = tmp.substr(0, tmp.find_last_of('/')); 383 | old = old.substr(old.find_last_of('/') + 1, old.length() - old.find_last_of('/')); 384 | curdir = pathTrans(tmp); 385 | if (curdir == NULL) { 386 | curdir = t; 387 | printf("Wrong Path!\n"); 388 | return; 389 | } 390 | } 391 | if (option == "-d") { 392 | if (curdir->next.find(old) == curdir->next.end()) { 393 | cout << "No Such Directory.\n"; 394 | } 395 | else if (curdir->next.find(newname) != curdir->next.end()) { 396 | cout << "There is a directory having same name.\n"; 397 | } 398 | else { 399 | dir *tmp = curdir->next[old]; 400 | curdir->next.erase(old); 401 | tmp->name = newname; 402 | curdir->next[newname] = tmp; 403 | } 404 | } 405 | else if (option == "-f") { 406 | if (curdir->files.find(old) == curdir->files.end()) { 407 | cout << "No Such File.\n"; 408 | } 409 | else if (curdir->files.find(newname) != curdir->files.end()) { 410 | cout << "There is a same file.\n"; 411 | } 412 | else if (curdir->files[old]->owner.name != curuser.name) { 413 | cout << "This file is not yours!\n"; 414 | } 415 | else { 416 | file *tmp = curdir->files[old]; 417 | curdir->files.erase(old); 418 | tmp->name = newname; 419 | curdir->files[newname] = tmp; 420 | } 421 | } 422 | else { 423 | cout << "Wrong Option!\n"; 424 | } 425 | curdir = t; 426 | } 427 | 428 | //递归删除目录 429 | void deletedir(dir *cur) { 430 | //先删文件 431 | for (auto it = cur->files.begin(); it != cur->files.end(); it++) { 432 | delete(it->second); 433 | } 434 | cur->files.clear(); 435 | //再删目录,要嵌套删除 436 | for (auto it = cur->next.begin(); it != cur->next.end(); it++) { 437 | deletedir(it->second); 438 | } 439 | cur->next.clear(); 440 | delete(cur); 441 | } 442 | 443 | //删除 444 | void rm(string tmp) { 445 | string option = ""; 446 | dir *t = curdir; 447 | if (tmp.find_first_of('-') != tmp.npos&&tmp.length() >= 2) { 448 | option = tmp.substr(tmp.find_first_of('-'), 2); 449 | } 450 | else { 451 | cout << "Wrong Option!\n"; 452 | return; 453 | } 454 | string name = ""; 455 | name = tmp.substr(tmp.find_first_of('-') + 3, tmp.length() - tmp.find_first_of('-') - 3); 456 | if (name.find_last_of('/') != name.npos) { 457 | string tmp = name; 458 | if (tmp[0] == '/') tmp = "~" + tmp; 459 | tmp = tmp.substr(0, tmp.find_last_of('/')); 460 | name = name.substr(name.find_last_of('/') + 1, name.length() - name.find_last_of('/')); 461 | curdir = pathTrans(tmp); 462 | if (curdir == NULL) { 463 | curdir = t; 464 | printf("Wrong Path!\n"); 465 | return; 466 | } 467 | } 468 | if (name == "") { 469 | cout << "Require Parameters" << endl; 470 | } 471 | else if (option == "-d") { 472 | if (curdir->next.find(name) == curdir->next.end()) { 473 | cout << "No Such Directory.\n"; 474 | } 475 | else { 476 | deletedir(curdir->next[name]); 477 | curdir->next.erase(name); 478 | } 479 | } 480 | else if (option == "-f") { 481 | if (curdir->files.find(name) == curdir->files.end()) { 482 | cout << "No Such File.\n"; 483 | } 484 | else if (curdir->files[name]->owner.name != curuser.name) { 485 | cout << "This file is not yours!\n"; 486 | } 487 | else { 488 | delete(curdir->files[name]); 489 | curdir->files.erase(name); 490 | } 491 | } 492 | else { 493 | cout << "Wrong Option!\n"; 494 | } 495 | } 496 | 497 | //递归复制目录 498 | dir* cpDir(dir *tmp) { 499 | dir *goal = new dir(*tmp); 500 | //清除原来的内容 501 | goal->next.clear(); 502 | goal->files.clear(); 503 | //把文件重建 504 | for (auto it = tmp->files.begin(); it != tmp->files.end(); it++) { 505 | file *f = new file(*(it->second)); 506 | goal->files[it->first] = f; 507 | } 508 | //重建目录 509 | for (auto it = tmp->next.begin(); it != tmp->next.end(); it++) { 510 | dir *d = cpDir(it->second); 511 | d->pre = goal; 512 | goal->next[it->first] = d; 513 | } 514 | return goal; 515 | } 516 | 517 | //复制 518 | void cp(string tmp) { 519 | string option = ""; 520 | if (tmp.find_first_of('-') != tmp.npos&&tmp.length() >= 3) { 521 | option = tmp.substr(tmp.find_first_of('-'), tmp.find_first_of(' ', tmp.find_first_of('-')) - tmp.find_first_of('-')); 522 | } 523 | else { 524 | cout << "Wrong Option!\n"; 525 | return; 526 | } 527 | string source = "", dest = "", name = ""; 528 | source = tmp.substr(tmp.find_first_of(' ', tmp.find_first_of('-')) + 1, tmp.find_last_of(' ') - tmp.find_first_of(' ', tmp.find_first_of('-')) - 1); 529 | dest = tmp.substr(tmp.find_last_of(' ') + 1, tmp.length() - tmp.find_last_of(' ')); 530 | dir *sou = NULL, *den = NULL; 531 | if (source.find_first_of("/") == source.npos) { 532 | sou = curdir; 533 | name = source; 534 | } 535 | else { 536 | if (source[0] == '/') source = "~" + source; 537 | name = source.substr(source.find_last_of('/') + 1, source.length() - source.find_last_of('/')); 538 | source = source.substr(0, source.find_last_of('/')); 539 | sou = pathTrans(source); 540 | } 541 | den = pathTrans(dest); 542 | if (den == NULL) { 543 | printf("Wrong Path!\n"); 544 | } 545 | else if (option == "-f") { 546 | if (sou == NULL) { 547 | printf("No Such File.\n"); 548 | return; 549 | } 550 | else { 551 | if (den->files.find(name) != den->files.end()) { 552 | cout << "Destination has a same file.\n"; 553 | return; 554 | } 555 | else if (sou->files.find(name) == sou->files.end()) { 556 | printf("No Such File.\n"); 557 | return; 558 | } 559 | else if (curdir->files[name]->owner.name != curuser.name) { 560 | cout << "This file is not yours!\n"; 561 | } 562 | else { 563 | file *tmp = new file(*(sou->files[name])); 564 | den->files[name] = tmp; 565 | } 566 | } 567 | } 568 | else if (option == "-d") { 569 | if (sou == NULL) { 570 | printf("No Such Directory.\n"); 571 | } 572 | else { 573 | if (den->next.find(name) != den->next.end()) { 574 | cout << "Destination has a same directory.\n"; 575 | return; 576 | } 577 | else if (sou->next.find(name) == sou->next.end()) { 578 | printf("No Such Directory.\n"); 579 | return; 580 | } 581 | else { 582 | dir *tmp = cpDir(sou->next[name]); 583 | tmp->pre = den; 584 | den->next[name] = tmp; 585 | } 586 | } 587 | } 588 | else if (option == "-cf") { 589 | if (sou == NULL) { 590 | printf("No Such File.\n"); 591 | return; 592 | } 593 | else { 594 | if (den->files.find(name) != den->files.end()) { 595 | cout << "Destination has a same file.\n"; 596 | return; 597 | } 598 | else if (sou->files.find(name) == sou->files.end()) { 599 | printf("No Such File.\n"); 600 | return; 601 | } 602 | else if (curdir->files[name]->owner.name != curuser.name) { 603 | cout << "This file is not yours!\n"; 604 | } 605 | else { 606 | den->files[name] = sou->files[name]; 607 | sou->files.erase(name); 608 | } 609 | } 610 | } 611 | else if (option == "-cd") { 612 | if (sou == NULL) { 613 | printf("No Such Directory.\n"); 614 | } 615 | else { 616 | if (den->next.find(name) != den->next.end()) { 617 | cout << "Destination has a same directory.\n"; 618 | return; 619 | } 620 | else if (sou->next.find(name) == sou->next.end()) { 621 | printf("No Such Directory.\n"); 622 | return; 623 | } 624 | else { 625 | den->next[name] = sou->next[name]; 626 | sou->next.erase(name); 627 | } 628 | } 629 | } 630 | else { 631 | cout << "Wrong Option!\n"; 632 | } 633 | 634 | } 635 | 636 | //清屏 637 | void cls() { 638 | system("cls"); 639 | } 640 | 641 | //切换用户 642 | void su() { 643 | login(); 644 | } 645 | 646 | //存储目前情况 647 | void save(dir *tmp) { 648 | records.push_back(tmp->name);//目录名 649 | records.push_back(to_string(tmp->files.size()));//文件数 650 | for (auto it = tmp->files.begin(); it != tmp->files.end(); it++) { 651 | records.push_back(it->second->name);//文件名 652 | for (int i = 0; i < it->second->content.size(); i++) { 653 | records.push_back( it->second->content[i]);//文件内容 654 | } 655 | records.push_back("content");//文件内容结束符 656 | records.push_back(it->second->owner.name);//所有者用户名 657 | records.push_back(it->second->owner.password);//所有者密码 658 | } 659 | records.push_back(to_string(tmp->next.size()));//子目录数 660 | for (auto it = tmp->next.begin(); it != tmp->next.end(); it++) { 661 | records.push_back(it->second->name);//子目录名 662 | save(it->second);//递归子目录 663 | } 664 | } 665 | 666 | //还原上一次系统关闭状态 667 | dir* creat(dir *last) { 668 | dir *tmp = new dir();//新建目录 669 | tmp->name=records[reco++];//读取目录名 670 | tmp->pre = last;//设置父指针 671 | string t; 672 | t= records[reco++];//读取文件数 673 | for (int i = 0; i < stoi(t); i++) { 674 | file *tfile = new file();//新建文件 675 | tfile->name= records[reco++];//读取文件名 676 | while (1) { 677 | string ts; 678 | ts= records[reco++];//读取文件内容 679 | if (ts != "content") {//不是关键字就持续读入内容 680 | tfile->content.push_back(ts); 681 | } 682 | else { 683 | break; 684 | } 685 | } 686 | user a; 687 | a.name = records[reco++];//读取用户名 688 | a.password= records[reco++];//密码 689 | tfile->owner = a; 690 | tmp->files[tfile->name] = tfile;//将新建的文件加入目录 691 | } 692 | t= records[reco++];//子目录数 693 | for (int i = 0; i < stoi(t); i++) { 694 | string name; 695 | name= records[reco++];//子目录名 696 | tmp->next[name] = creat(tmp);//递归新建子目录 697 | } 698 | return tmp; 699 | } 700 | 701 | void init() { 702 | ifstream inr("record.dat"); 703 | string tmp; 704 | if (!inr) { 705 | initDir(); 706 | } 707 | while (inr >> tmp) 708 | records.push_back(tmp); 709 | if (records.size() >= 1) { 710 | root = curdir = creat(NULL); 711 | } 712 | else { 713 | initDir(); 714 | } 715 | } 716 | 717 | 718 | //退出系统 719 | void exit() { 720 | records.clear(); 721 | save(root); 722 | ofstream outr("record.dat"); 723 | for (int i = 0; i < records.size(); i++) { 724 | outr << records[i] << endl; 725 | } 726 | } 727 | 728 | 729 | int main() { 730 | init(); 731 | login(); 732 | string command; 733 | while (1) { 734 | cout << curuser.name << "@" << curuser.name << "-FileSystem:"; 735 | displayPath(); 736 | getline(cin, command); 737 | string tmp = command; 738 | if (command.find_first_of(' ') != command.npos) { 739 | command = command.substr(0, command.find_first_of(' ')); 740 | tmp = tmp.substr(tmp.find_first_of(' ') + 1, tmp.length() - tmp.find_first_of(' ')); 741 | } 742 | else tmp = ""; 743 | if (command == "help") help(); 744 | else if (command == "mkdir") mkdir(tmp); 745 | else if (command == "cd") cd(tmp); 746 | else if (command == "touch") touch(tmp); 747 | else if (command == "ls") ls(tmp); 748 | else if (command == "gedit") gedit(tmp); 749 | else if (command == "rename") rename(tmp); 750 | else if (command == "rm") rm(tmp); 751 | else if (command == "cp") cp(tmp); 752 | else if (command == "cls") cls(); 753 | else if (command == "su") su(); 754 | else if (command == "exit") { 755 | exit(); 756 | return 0; 757 | } 758 | else help2(command); 759 | } 760 | system("pause"); 761 | } 762 | 763 | -------------------------------------------------------------------------------- /文件系统/record - 副本.txt: -------------------------------------------------------------------------------- 1 | ~ 2 | 0 3 | 2 4 | 1 5 | 1 6 | 1 7 | 4 8 | 12 9 | 12 10 | 12 11 | content 12 | 1 13 | 1 14 | 1 15 | 3 16 | 3 17 | 0 18 | 0 19 | 2 20 | 2 21 | 0 22 | 0 23 | -------------------------------------------------------------------------------- /文件系统/record.dat: -------------------------------------------------------------------------------- 1 | ~ 2 | 0 3 | 2 4 | 1 5 | 1 6 | 1 7 | tmp.txt 8 | hello 9 | word 10 | guys 11 | content 12 | 1 13 | 1 14 | 0 15 | 2 16 | 2 17 | 1 18 | tmp.txt 19 | content 20 | 1 21 | 1 22 | 0 23 | -------------------------------------------------------------------------------- /文件系统/record.txt: -------------------------------------------------------------------------------- 1 | ~ 2 | 0 3 | 2 4 | 1 5 | 1 6 | 1 7 | 4 8 | 12 9 | 12 10 | 12 11 | content 12 | 1 13 | 1 14 | 1 15 | 3 16 | 3 17 | 0 18 | 0 19 | 2 20 | 2 21 | 0 22 | 0 23 | -------------------------------------------------------------------------------- /文件系统/save.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/szr712/FileSystem/34372149d6dd4a0971acdb4da3cc4d005ad293f7/文件系统/save.bin -------------------------------------------------------------------------------- /文件系统/tmp.dat: -------------------------------------------------------------------------------- 1 | hello 2 | word 3 | guys 4 | -------------------------------------------------------------------------------- /文件系统/user.dat: -------------------------------------------------------------------------------- 1 | 1 1 2 | 2 2 3 | s 1 4 | szr 123456 5 | -------------------------------------------------------------------------------- /文件系统/文件系统.vcxproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Debug 6 | Win32 7 | 8 | 9 | Release 10 | Win32 11 | 12 | 13 | Debug 14 | x64 15 | 16 | 17 | Release 18 | x64 19 | 20 | 21 | 22 | 15.0 23 | {D0B0D89A-3A53-49AC-AA3A-A3F48139AEBD} 24 | 文件系统 25 | 10.0.17763.0 26 | 27 | 28 | 29 | Application 30 | true 31 | v141 32 | Unicode 33 | 34 | 35 | Application 36 | false 37 | v141 38 | true 39 | Unicode 40 | 41 | 42 | Application 43 | true 44 | v141 45 | Unicode 46 | 47 | 48 | Application 49 | false 50 | v141 51 | true 52 | Unicode 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | Level3 76 | Disabled 77 | true 78 | true 79 | 80 | 81 | 82 | 83 | Level3 84 | Disabled 85 | true 86 | true 87 | 88 | 89 | 90 | 91 | Level3 92 | MaxSpeed 93 | true 94 | true 95 | true 96 | true 97 | 98 | 99 | true 100 | true 101 | 102 | 103 | 104 | 105 | Level3 106 | MaxSpeed 107 | true 108 | true 109 | true 110 | true 111 | 112 | 113 | true 114 | true 115 | 116 | 117 | 118 | 119 | 120 | 121 | 122 | 123 | -------------------------------------------------------------------------------- /文件系统/文件系统.vcxproj.filters: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | {4FC737F1-C7A5-4376-A066-2A32D752A2FF} 6 | cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx 7 | 8 | 9 | {93995380-89BD-4b04-88EB-625FBE52EBFB} 10 | h;hh;hpp;hxx;hm;inl;inc;ipp;xsd 11 | 12 | 13 | {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} 14 | rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms 15 | 16 | 17 | 18 | 19 | 源文件 20 | 21 | 22 | -------------------------------------------------------------------------------- /文件系统/文件系统.vcxproj.user: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | false 5 | 6 | -------------------------------------------------------------------------------- /文件系统/源.cpp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/szr712/FileSystem/34372149d6dd4a0971acdb4da3cc4d005ad293f7/文件系统/源.cpp --------------------------------------------------------------------------------