目录

实验要求

一、文件管理和用户接口

⑴文件的逻辑结构

⑵磁盘模拟

⑶目录结构

⑷磁盘分配

⑸磁盘空闲存储空间管理

⑹用户接口

⑺屏幕显示

代码部分

python调用c的方法:

​编辑

c语言部分,文件名 Operating_System_C.c

python语言部分

运行实例:


实验要求

一、文件管理和用户接口

文件管理和用户接口部分实现的主要是单用户的磁盘文件管理部分,包括文件的逻辑结构、物理结构、目录、磁盘分配回收、文件的保护和用户接口的实现。

文件的逻辑结构

文件的逻辑结构采用流式结构;

文件均采用文本文件;

系统中有两种文件,一种是存放任意字符的文件,一种是可执行文件。可执行文件的内容就是模拟系统内进程的程序体。

文件中的“可执行”文件,包含的命令非常简单,包括:

x=?; x 赋值一位数
x++;  x 1
x--;    x 1
!?? 第一个?为 A,B,C 中某个设备,第二个?为一位数,表示使用设备的时间(由于没有实际设备,所以无法知道设备何时工作完成,所以假定一个数,这个数随着系统时间增加而递减,减到 0 时,认为是设备工作完成)
end. 表示文件结束,同时将结果写入文件 out ,其中包括文件路径名和 x 的值。

磁盘模拟

用一个文本文件disk模拟磁盘,磁盘的每个盘块64字节,模拟磁盘共有128块。第01块存放文件分配表,第2块存放根目录,其余存放子目录和文件。

目录结构

目录结构采用树型目录结构。

①目录项内容(8个字节):

目录名、文件名:3 个字节;
扩展名:2 个字节(可执行文件扩展名为 e ,目录没有扩展名);
目录、文件属性:1 字节;
起始盘块号:1 个字节;
文件长度:1 字节(目录没有长度)。

根目录

根目录位置固定,占用模拟磁盘第2块,大小固定,共8项;

③子目录

位置不固定,大小不固定。(至少建立一级子目录,最好支持多级子目录)

磁盘分配

磁盘的分配采用链接结构(显式链接)的分配。

⑸磁盘空闲存储空间管理

磁盘空闲存储空间管理采用位示图方法。

位示图和显示链接的指针合在一起组成文件分配表,占用磁盘空间第01

用户接口

用户接口提供用户命令接口,要求实现以下命令:

创建文件:create 拷贝文件:copy

删除文件:delete 移动文件:move

显示文件:type 改变文件属性:change

建立目录:makdir     改变目录路径:chadir

删除目录:deldir(deltree) 修改文件 edit

运行可执行文件:可执行文件的文件名(创建进程)。

屏幕显示

屏幕显示要求包括:

n 用户命令接口:用于系统运行时用户输入命令
n 磁盘目录显示:要求显示磁盘的树型目录结构
n 磁盘使用情况:显示磁盘每一个磁盘块的空间是占用还是空闲

代码部分

c和python各1000多行

python调用c的方法:

python导入ctypes库,在pycham控制台输入

gcc Operating_System_C.c -shared -o Operating_System_C.dll

若提示

可能是你的路径不对,注意切换到.c文件的目录

若提示,没有gcc之类的,请去MinGW-w64 - for 32 and 64 bit Windows - Browse Files at SourceForge.netA complete runtime environment for gcchttps://sourceforge.net/projects/mingw-w64/files/

下载

  • x86_64-posix-sehhttps://sourceforge.net/projects/mingw-w64/files/Toolchains%20targetting%20Win64/Personal%20Builds/mingw-builds/8.1.0/threads-posix/seh/x86_64-8.1.0-release-posix-seh-rt_v6-rev0.7z

这是我下载的文件,仅需1积分(友情链接)

并把压缩包解压,将含有g++.exe的文件路径添加到环境变量中

打开cmd 输入gcc --version 若弹出以下内容

表明安装完成

然后就可以用

Operating_System_C = ctypes.cdll.LoadLibrary('./Operating_System_C.dll')

打开自己写的c文件,调用其中的函数了(函数默认返回值为ctypes.c_int类型,函数的输入也要转化为ctypes的类型才行,具体情况请自己去搜索ctypes教程)

c语言部分,文件名 Operating_System_C.c

需要在控制台输入

gcc Operating_System_C.c -shared -o Operating_System_C.dll

生成.dll文件才能被python调用

#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>// 目录项
/*
目录名、文件名:3个字节;
扩展名:2个字节(可执行文件扩展名为e,目录没有扩展名);
目录、文件属性:1字节;
起始盘块号:1个字节;
文件长度:1字节(目录没有长度)。
*/
struct catalog_entry{char name[3];char extend[2];unsigned char attribute : 8;   // 1目录,2文件,0不存在unsigned char start : 8;unsigned char len : 8;
};// 八位数据类型,主要用于位视图
union bit8{
unsigned char data : 8;
struct bits8{   // 注意排列 b0 b1 b2 b3 b4 b5 b6 b7unsigned char b7 : 1;unsigned char b6 : 1;unsigned char b5 : 1;unsigned char b4 : 1;unsigned char b3 : 1;unsigned char b2 : 1;unsigned char b1 : 1;unsigned char b0 : 1;
}bit8;
};// 索引7*8
union index56{
unsigned char datas[7];
};// 索引变量 记录索引的值
unsigned char index_variables[128];// 位视图
union bit8 bitwise_view[16];// 文件变量
FILE* file;// 输出文件
FILE* fp;// 保存位视图,给出块号,保存它,负数保存所有
void Save_Bitview(FILE* file,int position){if(position<0){fseek(file,0,SEEK_SET);    // 文件指针移动fwrite(bitwise_view,1,16,file);}else{char t[1] = {bitwise_view[position/8].data};fseek(file,position/8,SEEK_SET);    // 文件指针移动fwrite(t,1,1,file);}
}// 从位视图中返回一个空块的位置失败返回-1
int Give_Empty_Block(){int i,j;for(i=0;i<16;i++){if(bitwise_view[i].bit8.b0 == 0)return i*8+0;if(bitwise_view[i].bit8.b1 == 0)return i*8+1;if(bitwise_view[i].bit8.b2 == 0)return i*8+2;if(bitwise_view[i].bit8.b3 == 0)return i*8+3;if(bitwise_view[i].bit8.b4 == 0)return i*8+4;if(bitwise_view[i].bit8.b5 == 0)return i*8+5;if(bitwise_view[i].bit8.b6 == 0)return i*8+6;if(bitwise_view[i].bit8.b7 == 0)return i*8+7;}return -1;
}// 占用块,成功1,失败-1
int Occupy_Block(FILE* file,int i){switch(i%8){    // 挨个位看case 0:if(bitwise_view[i/8].bit8.b0==1){return -1;}else{bitwise_view[i/8].bit8.b0=1;}break;case 1:if(bitwise_view[i/8].bit8.b1==1){return -1;}else{bitwise_view[i/8].bit8.b1=1;}break;case 2:if(bitwise_view[i/8].bit8.b2==1){return -1;}else{bitwise_view[i/8].bit8.b2=1;}break;case 3:if(bitwise_view[i/8].bit8.b3==1){return -1;}else{bitwise_view[i/8].bit8.b3=1;}break;case 4:if(bitwise_view[i/8].bit8.b4==1){return -1;}else{bitwise_view[i/8].bit8.b4=1;}break;case 5:if(bitwise_view[i/8].bit8.b5==1){return -1;}else{bitwise_view[i/8].bit8.b5=1;}break;case 6:if(bitwise_view[i/8].bit8.b6==1){return -1;}else{bitwise_view[i/8].bit8.b6=1;}break;case 7:if(bitwise_view[i/8].bit8.b7==1){return -1;}else{bitwise_view[i/8].bit8.b7=1;}break;}// 保存更改Save_Bitview(file,i);char t[1];int j;// 清空原有块中的东西fseek(file,i*64,SEEK_SET);    // 文件指针移动t[0] = 0b00000000;for(j=0;j<64;j++)   // 0掩盖fwrite(t,1,1,file);return 1;
}// 取消占用块
void Unoccupie_Block(FILE* file,int i){switch(i%8){    // 挨个位看case 0:bitwise_view[i/8].bit8.b0=0;break;case 1:bitwise_view[i/8].bit8.b1=0;break;case 2:bitwise_view[i/8].bit8.b2=0;break;case 3:bitwise_view[i/8].bit8.b3=0;break;case 4:bitwise_view[i/8].bit8.b4=0;break;case 5:bitwise_view[i/8].bit8.b5=0;break;case 6:bitwise_view[i/8].bit8.b6=0;break;case 7:bitwise_view[i/8].bit8.b7=0;break;}// 保存更改Save_Bitview(file,i);
}// 返回索引最后一个块的编号
int Index_End(int x){if (index_variables[x] == 0){ // 末尾0,索引到了return x;}else{Index_End(index_variables[x]);    // 继续}
}// 保存索引表,给出块号,保存它,负数保存所有
void Save_Index(FILE* file,int position){union index56 index_pointer[1];//索引指针,保存用int i,j;if(position<0){fseek(file,16,SEEK_SET);    // 文件指针移动for(i=0;i<16;i++){index_pointer[0].datas[6] = index_variables[i*8+7];for(j=6;j>=0;j--){index_pointer[0].datas[j] += index_variables[i*8+j]<<j+1;if(j!=0){index_pointer[0].datas[j-1] = index_variables[i*8+j]>>7-j;}}fwrite(index_pointer,7,1,file);}}else{fseek(file,16+position/8*7,SEEK_SET);    // 文件指针移动i = position/8*8;index_pointer[0].datas[6] = index_variables[i+7];for(j=6;j>=0;j--){index_pointer[0].datas[j] += index_variables[i+j]<<j+1;if(j!=0){index_pointer[0].datas[j-1] = index_variables[i+j]>>7-j;}}fwrite(index_pointer,7,1,file);}}// 删除索引,连着删除这一块后面所有的索引,同时取消块占用
void Drop_Index(FILE* file,int x){if (index_variables[x] != 0){ // 不是最后一个Drop_Index(file,index_variables[x]);  // 往下走index_variables[x] = 0; // 删除该索引Save_Index(file,x);    // 保存索引表}Unoccupie_Block(file,x); //取消块占用// 末尾0,索引结束
}// 保存位视图和索引表,
void Save_Start(FILE* file){union index56 index_pointer[1];//索引指针,保存用int i,j;fseek(file,0,SEEK_SET);    // 文件指针移动fwrite(bitwise_view,1,16,file);for(i=0;i<16;i++){index_pointer[0].datas[6] = index_variables[i*8+7];for(j=6;j>=0;j--){index_pointer[0].datas[j] += index_variables[i*8+j]<<j+1;if(j!=0){index_pointer[0].datas[j-1] = index_variables[i*8+j]>>7-j;}}fwrite(index_pointer,7,1,file);}
}// 读取位视图和索引表
void Read_Start(FILE* file){fseek(file,0,SEEK_SET);    // 文件指针移动// 数据数组,每个元素字节,元素个数,输入文件位置fread(bitwise_view,1,16,file);int i,j;union index56 index_pointer[1];//索引指针,读取用for(i=0;i<16;i++){fread(index_pointer,7,1,file);index_variables[i*8] = index_pointer[0].datas[0]>>1;for(j=0;j<7;j++){index_variables[i*8+j+1] = (index_pointer[0].datas[j]<<(6-j))%128;if(j!=6){index_variables[i*8+j+1] += index_pointer[0].datas[j+1]>>(j+2);}}}
}// 查看目录在块中文件是否存满,存满返回-1,否则返回第一个空的文件位置(字节位置)
// 带递归翻页
int Directory_Overrun(FILE* file,int start,int len){if(start==0){ // 空了,前面都没找到return -1;}fseek(file,64*start,SEEK_SET);    // 文件指针移动struct catalog_entry directory[8];  // 读取到的目录fread(directory,8,8,file);// 读取int i;for(i=0;i<8;i++){if(directory[i].attribute==0){return 64*start+8*i;}}return Directory_Overrun(file,index_variables[start],len-1);    // 到这里没有,看看下一页
}// 输出位视图
void Printf_Bitwise_View(){int i;fprintf(fp,"\n位视图:");for(i=0;i<16;i++){fprintf(fp,"\n%d",bitwise_view[i].bit8.b0);fprintf(fp,"  %d",bitwise_view[i].bit8.b1);fprintf(fp,"  %d",bitwise_view[i].bit8.b2);fprintf(fp,"  %d",bitwise_view[i].bit8.b3);fprintf(fp,"  %d",bitwise_view[i].bit8.b4);fprintf(fp,"  %d",bitwise_view[i].bit8.b5);fprintf(fp,"  %d",bitwise_view[i].bit8.b6);fprintf(fp,"  %d",bitwise_view[i].bit8.b7);}fprintf(fp,"\n");
}// 输出索引阵列
void Printf_Index_variables(){int i,j;fprintf(fp,"\n索引变量\n");for(i=0;i<16;i++){for(j=0;j<8;j++){fprintf(fp,"%5d",index_variables[i*8+j]);}fprintf(fp,"\n");}
}// 输出目录
void Printf_Entry(struct catalog_entry entry){if(entry.attribute == 0){fprintf(fp,"\n目录不存在");return;}fprintf(fp,"\n名称:");int i;for(i=0;i<3;i++){if(entry.name[i]!='\0'){fprintf(fp,"%c",entry.name[i]);}else{break;}}if(entry.attribute > 1){fprintf(fp,"\n扩展名:");for(i=0;i<2;i++){if(entry.extend[i]!='\0'){fprintf(fp,"%c",entry.extend[i]);}else{if(i==0){fprintf(fp,"无");}break;}}}fprintf(fp,"\n属性:");switch(entry.attribute){case 0: fprintf(fp,"不存在");break;case 1: fprintf(fp,"目录");break;case 2: fprintf(fp,"文件");break;default:    fprintf(fp,"其他");break;}fprintf(fp," %d",entry.attribute);fprintf(fp,"\n起始块:%d\n长度:%d\n",entry.start,entry.len);
}// 生成目录项
// 名字,扩展名,属性,起始块号,文件长度
struct catalog_entry Generate_Catalog_Entry(char* name,char* extend,int attribute,int start,int len){struct catalog_entry entry = {"","",attribute,start,len};entry.name[0]=name[0];entry.name[1]=name[1];entry.name[2]=name[2];entry.extend[0]=extend[0];entry.extend[1]=extend[1];return entry;
}// 在块中按名查找文件或目录,返回目录项,同时最后一个数据指针的值更改为文件目录项字节位置,没有不会更改
struct catalog_entry LookUp(FILE* file,char* name,int start,int len,int *p){struct catalog_entry directory[8]; // 读取到的目录if(start==0){ // 空了,前面都没找到directory[0].attribute = 0;return directory[0];}fseek(file,64*start,SEEK_SET);    // 文件指针移动fread(directory,8,8,file);// 读取int i;for(i=0;i<8;i++){if(directory[i].attribute!=0){// 这个东西存的有// 开始名称匹配if(directory[i].name[0]==name[0]){// 第一个匹配if(name[0]=='\0'){// 结束了*p = start*64+i*8;return directory[i];}else{if(directory[i].name[1]==name[1]){// 第二个匹配if(name[1]=='\0'){// 结束了*p = start*64+i*8;return directory[i];}else{if(directory[i].name[2]==name[2]){// 第三个匹配*p = start*64+i*8;return directory[i];}}}}}}}return LookUp(file,name,index_variables[start],len-1,p);    // 到这里没有,看看下一页
}// 目录长度改变,要改变的目录,改变值
void Directory_Length_Chenge(FILE* file,struct catalog_entry entry,int change){char lend[1] = {entry.len+change};struct catalog_entry directory[1]; // 读取到的目录int t;int *p=&t;fseek(file,64*entry.start+7,SEEK_SET);    // 文件指针移动到当前目录的长度属性fwrite(lend,1,1,file);  // 改变fseek(file,64*entry.start+8,SEEK_SET);    // 文件指针移动到父目录fread(directory,8,1,file);// 读取if(LookUp(file,entry.name,directory[0].start,directory[0].len,p).attribute == 0){ // 查找目录字节位置fprintf(fp,"\n严重错误,对目录的父目录中未找到自己,目录长度改变失败");// 没找到}else{fseek(file,t+7,SEEK_SET);  // 移动到该目录项的长度位置fwrite(lend,1,1,file);  // 改变}
}// 目录整理,整理参数中目录表指向的目录,顺便会删除空的目录项
// 带翻页,不整花活,直接暴力读取,排序,修改
int Catalog_Organization(FILE* file,struct catalog_entry entry){int i,j,k=entry.len-1,l=7,start=entry.start;struct catalog_entry directory[entry.len][8];for(i=0;i<entry.len;i++){   // 遍历每个块fseek(file,64*start,SEEK_SET);    // 文件指针移动fread(directory[i],8,8,file);// 读取start = index_variables[start]; // 下一块}i=0;j=entry.len*8-1;while(i!=j){// 撞上就停if(directory[i/8][i%8].attribute!=0){//i没指向一个空位i++;    // 前进}else{if(directory[j/8][j%8].attribute==0){//j没指向一个存在的位置j--;}else{// i指向空位,j指向一个存在的位置directory[i/8][i%8]=directory[j/8][j%8];    // 替换directory[j/8][j%8].attribute = 0;}}}i = (i-1)/8;// 看看指针停在第几块,就保存在前几块start=entry.start;for(j=0;j<=i;j++){// 遍历块保存新目录if(j==i){k = start;}fseek(file,64*start,SEEK_SET);    // 文件指针移动fwrite(directory[j],8,8,file);  // 保存start = index_variables[start]; // 下一块}if(start!=0){// 不是最后一块index_variables[k] = 0;Save_Index(file,k);    // 保存索引表Drop_Index(file,start);   // 删后面索引}Directory_Length_Chenge(file,entry,i-entry.len+1);   // 文件长度改变
}// 重建根目录
void Rebuild_Root_Directory(FILE* file){// 根目录位置固定,占用模拟磁盘第2块,大小固定,共8项;// 目录都包含当前目录.和父目录..  采用.=..表示根目录。struct catalog_entry root_directory[2];char name[3]={'.','\0','\0'};char extend[2]={'\0','\0'};int i;// 只用一个struct catalog_entry更经济,但这么写更直观root_directory[0] = Generate_Catalog_Entry(name,extend,1,2,1); // 当前目录name[1] = '.';root_directory[1] = Generate_Catalog_Entry(name,extend,1,2,1); // 父目录fseek(file,64*2,SEEK_SET);    // 文件指针移动fwrite(root_directory,8,2,file);    // 保存两个特殊目录项name[0] = 0;for(i=16;i<128;i++){fwrite(name,1,1,file);}}void Reset_Disk()   // 重置磁盘,直接新建磁盘文件,删除之前所有记录
{FILE* file;file = fopen("disk.txt","w+");  // 创建磁盘文件fprintf(fp,"\n已重新创建磁盘文件 disk.txt ");// disk是模拟磁盘,开始生成模拟磁盘的数据// 磁盘的分配采用链接结构(显式链接)的分配。// 共有128块,每个盘块64字节,共8192字节// 第0、1块存放文件分配表,位示图和显示链接的指针合在一起组成文件分配表// 第2块存放根目录,其余存放子目录和文件// 位视图要有128位,即16字节// 初始第0、1、2块都在占用int i,j;bitwise_view[0].data = 0b11100000;// 前三块必定被占用,for(i=1;i<16;i++){bitwise_view[i].data = 0;   // 其余暂时置0}// 数据数组,每个元素字节,元素个数,输出到文件位置// 128个块,索引只需7位,刚好(7*128)/4+16=128占两个块for(i=0;i<128;i++){ //索引置0index_variables[i] = 0;}Save_Start(file);// 保存位视图和索引表Rebuild_Root_Directory(file);// 重建根目录// 填补剩下的磁盘char t[1] = {0b0};fseek(file,64*3,SEEK_SET);    // 文件指针移动for(i=192;i<8192;i++){fwrite(t,1,1,file);}fclose(file);
}// 创建文件,成功返回块号,否则-1   文件名,扩展名,目录 ,文件属性(目录1,文件>1)
int Create(FILE* file,char* name,char* extend,struct catalog_entry entry,char attribute){if(attribute <= 0){fprintf(fp,"\n创建参数错误,创建失败");return -1;}int position = Directory_Overrun(file,entry.start,entry.len);  // 找找空位if(position == -1){// 没找到空位if(entry.start == 2){   // 是根目录fprintf(fp,"\n根目录已满,无法创建");// 根目录只能有1页return -1;}else{ // 否则可以新增一页int piece = Give_Empty_Block(); // 找一个新块if(piece==-1){  // 找不到fprintf(fp,"\n磁盘已满,无法创建");return -1;}else{ // 新增一页int iend = Index_End(entry.start);// 找到目录的末页Occupy_Block(file,piece);   // 占用新块,刚找到的新块,就不看在不在了index_variables[iend] = piece;    // 索引延申Save_Index(file,iend); // 改完索引要保存// 新增页了,文件长度需要+1Directory_Length_Chenge(file,entry,1);position = piece*64;    // 新的空位在新页的第一格// 由于都重置为0,里面的文件,目录属性也应该是0}}}// 找找有没有同名的,同名抛弃int t;int *p=&t;if(LookUp(file,name,entry.start,entry.len,p).attribute!=0){// 找到同名fprintf(fp,"\n发现同名,创建失败,位置在%d字节处",t);return -1;}// 到这里没返回就找到一个空位了int piece1 = Give_Empty_Block(); // 找一个新块if(piece1==-1){  // 找不到fprintf(fp,"\n磁盘已满,无法创建");return -1;}else{Occupy_Block(file,piece1);   // 占用新块,刚找到的新块,就不看在不在了struct catalog_entry directory[1];// 新目录项directory[0] = Generate_Catalog_Entry(name,extend,attribute,piece1,1);// 创建的目录项fseek(file,position,SEEK_SET);    // 文件指针移动fwrite(directory,8,1,file); // 目录的保存return piece1;}
}// 删除文件,成功返回1否则-1   文件名,目录
// 拒绝删除目录文件
int Delete(FILE* file,char* name,struct catalog_entry entry){int t;  // 字节位置int *p=&t;char k[1];struct catalog_entry directory[1]; // 读到的目录项directory[0] = LookUp(file,name,entry.start,entry.len,p);// 找位置if(directory[0].attribute == 0){    // 不存在fprintf(fp,"\n未找到删除对象");return -1;}else{if(directory[0].attribute == 1){fprintf(fp,"\n拒绝使用文件删除来删除目录");return -1;}k[0] = 0;directory[0].attribute = 0;fseek(file,t+5,SEEK_SET);    // 文件指针移动,将属性改为不存在fwrite(k,1,1,file); // 目录更改完毕Drop_Index(file,directory[0].start);    // 删除索引表链接,同时取消块占用// 这里不做空白目录页的删除(目录整理,由用户手动执行)}return 1;
}// 建立目录 成功返回块号 否则-1 文件名,目录,套用创建文件,不过微改一点地方
int Makdir(FILE* file,char* name,struct catalog_entry entry){// 目录都包含当前目录.和父目录..  采用.=..表示根目录。char extend[2]={'\0','\0'};int t=Create(file,name,extend,entry,1);   // 生成目录if(t == -1){return -1;}struct catalog_entry root_directory[2];char name1[3]={'.','\0','\0'};int i;root_directory[0] = Generate_Catalog_Entry(name1,extend,1,t,1); // 当前目录name1[1] = '.';root_directory[1] = Generate_Catalog_Entry(name1,extend,1,entry.start,1); // 父目录fseek(file,64*t,SEEK_SET);    // 文件指针移动fwrite(root_directory,8,2,file);    // 保存两个特殊目录项// 占用块时,会格式化0,所以不用管后面的return t;
}// 删除目录,成功返回1否则-1   目录名,目录
// 拒绝删除根目录,会递归调用自己,删除所有子目录和文件。
int Deldir(FILE* file,char* name,struct catalog_entry entry){int t,i,j,start;  // 字节位置int *p=&t;char k[1];struct catalog_entry directory[1]; // 读到的目录项struct catalog_entry directory8[8];directory[0] = LookUp(file,name,entry.start,entry.len,p);// 找位置if(directory[0].attribute == 0){    // 不存在fprintf(fp,"\n未找到删除对象");return -1;}else{if(directory[0].start==2){fprintf(fp,"\n试图删除根目录,请求遭到拒绝");return -1;}if(directory[0].attribute != 1){fprintf(fp,"\n拒绝使用目录删除来删除文件");return -1;}// 开始递归删除要删除目录的所有内容start = directory[0].start; // 要读取目录的块for(i=0;i<directory[0].len;i++){fseek(file,start*64,SEEK_SET);    // 指针准备读取目录内容fread(directory8,8,8,file);// 读取for(j=0;j<8;j++){// 遍历块,根据类型来递归删除目录或者文件if(directory8[j].attribute==1&&(i!=0||j>1)){// 递归删除目录,不递归特殊目录项,因为特殊目录项都在第一块前两个,所以看i,j就行Deldir(file,directory8[j].name,directory[0]);}else{if(directory8[j].attribute>1){// 递归删除文件Delete(file,directory8[j].name,directory[0]);}}}start = index_variables[start]; // 准备读取下一块}Drop_Index(file,directory[0].start);    // 删除索引表链接,同时取消块占用// 在当前目录删除要删除的目录项k[0] = 0;directory[0].attribute = 0;fseek(file,t+5,SEEK_SET);    // 文件指针移动,将属性改为不存在fwrite(k,1,1,file); // 目录更改完毕// 这里不做空白目录页的删除(目录整理,由用户手动执行)}return 1;}// 显示文件 给出目录项块号和长度,显示目录项所包含的文件(目录文件和文本文件)无返回
void Type(FILE* file,int start,int len){struct catalog_entry directory[8]; // 读取到的目录if(start==0){ // 空了,结束return ;}fseek(file,64*start,SEEK_SET);    // 文件指针移动fread(directory,8,8,file);// 读取int i;for(i=0;i<8;i++){if(directory[i].attribute!=0){// 这个东西存的有Printf_Entry(directory[i]); // 输出目录项}}Type(file,index_variables[start],len-1);
}// 给出文件所在的目录和文件名,将字符数组的值赋值给文件,成功1,否则-1
// len单位:字节;可以直接用data的长度。这里会自动+1来带上\0,strlen(data)
int Edit(FILE* file,struct catalog_entry entry,char* name,char* data,int len){len++;// 怕64个的时候,没有\0终结int t;int *p = &t;struct catalog_entry directory=LookUp(file,name,entry.start,entry.len,p); // 获取文件目录项if(directory.attribute==0){fprintf(fp,"\n文件不存在");return -1;}float lenf = ((float)len)/64;    // 计算所需块数int leni = (int)lenf;leni = lenf - leni > 1e-3 ? (leni+1) : leni;    // 向上取整int i,j;char m[1];if(leni>directory.len){// 比原来长,加几块int iend = Index_End(directory.start);// 找到目录的末页for(i=directory.len+1;i<=leni;i++){int piece = Give_Empty_Block(); // 给一个空块if(piece==-1){fprintf(fp,"\n磁盘已满");return-1;}Occupy_Block(file,piece);   // 占用新块,刚找到的新块,就不看在不在了index_variables[iend] = piece;    // 索引延申Save_Index(file,iend); // 改完索引要保存// 新增块了,文件长度需要+1fseek(file,t+7,SEEK_SET);    // 文件指针移动到文件的长度属性m[0]=i;fwrite(m,1,1,file);  // 改变iend = index_variables[iend];}}else{if(leni<directory.len){// 比原来短,去几块j = directory.start;for(i=0;i<leni-1;i++){j=index_variables[j];   // 一直找,直到找到需要删除的索引位置}Drop_Index(file,index_variables[j]); // 删除索引,解除占用index_variables[j] = 0; // 删除该索引Save_Index(file,j);    // 保存索引表fseek(file,t+7,SEEK_SET);m[0]=leni;fwrite(m,1,1,file);  // 改变}}t = directory.start;for(i=0;i<leni;i++){    // 开始赋新值fseek(file,t*64,SEEK_SET);if(i==leni-1){  // 最后一块,小心行事fwrite(&data[i*64],1,len-i*64-1,file);  // 改变m[0]='\0';fwrite(m,1,1,file);  // 改变}else{fwrite(&data[i*64],1,64,file);  // 改变}t = index_variables[t];}
}// 拷贝文件,将文件拷贝到目录中(不支持目录文件拷贝)
// 返回拷贝的目录项成功,内核是创建一个同名文件,再赋值
struct catalog_entry Copy(FILE* file,struct catalog_entry document,struct catalog_entry entry){struct catalog_entry new_document;new_document.attribute = 0;if(document.attribute == 1){fprintf(fp,"\n禁止拷贝目录文件");return new_document;}if(document.attribute == 0){fprintf(fp,"\n被拷贝的文件不存在");return new_document;}int t = Create(file,document.name,document.extend,entry,document.attribute);if(t == -1){return new_document;}int i,j;int *p =&j;// 凑参数char data[64*document.len+1];   // 拷贝的文件内容data[64*document.len+1]='\0';   // 最后一个赋值j = document.start;for(i=0;i<document.len;i++){fseek(file,j*64,SEEK_SET);fread(&data[i*64],1,64,file);  // 读取j=index_variables[j];}Edit(file,entry,document.name,data,strlen(data));return LookUp(file,document.name,entry.start,entry.len,p);
}// 读取文件存到char*
void Read_File(FILE* file,struct catalog_entry entry,char* data){int i,j;j = entry.start;for(i=0;i<entry.len;i++){fseek(file,j*64,SEEK_SET);fread(&data[i*64],1,64,file);  // 读取j=index_variables[j];}
}// 移动文件,将文件移动到目录中(支持目录文件移动)
// 返回移动的目录项成功,内核是移动目录项到指定目录中
struct catalog_entry Move(FILE* file,struct catalog_entry directory,char* name,struct catalog_entry entry){int t;int *p = &t;int d;int *q=&d;char k[1]={0};struct catalog_entry document = LookUp(file,name,directory.start,directory.len,p);// 文件的目录项struct catalog_entry new_directory[1];// 新目录项new_directory[0] = document;if(new_directory[0].attribute == 0){fprintf(fp,"\n被移动的文件不存在");return document;}directory.attribute = 0;int position = Directory_Overrun(file,entry.start,entry.len);  // 找找空位if(position == -1){// 没找到空位if(entry.start == 2){   // 是根目录fprintf(fp,"\n根目录已满,无法移动");// 根目录只能有1页return document;}else{ // 否则可以新增一页int piece = Give_Empty_Block(); // 找一个新块if(piece==-1){  // 找不到fprintf(fp,"\n磁盘已满,无法移动");return document;}else{ // 新增一页int iend = Index_End(entry.start);// 找到目录的末页Occupy_Block(file,piece);   // 占用新块,刚找到的新块,就不看在不在了index_variables[iend] = piece;    // 索引延申Save_Index(file,iend); // 改完索引要保存// 新增页了,文件长度需要+1Directory_Length_Chenge(file,entry,1);position = piece*64;    // 新的空位在新页的第一格// 由于都重置为0,里面的文件,目录属性也应该是0}}}// 找找有没有同名的,同名抛弃if(LookUp(file,name,entry.start,entry.len,q).attribute!=0){// 找到同名fprintf(fp,"\n发现同名,移动失败,位置在%d字节处",t);return document;}// 到这里没返回就找到一个空位了fseek(file,t+5,SEEK_SET);    // 文件指针移动,将属性改为不存在fwrite(k,1,1,file); // 目录更改完毕fseek(file,position,SEEK_SET);    // 文件指针移动fwrite(new_directory,8,1,file); // 目录的保存if(new_directory[0].attribute == 1){ //目录还需要更改目录中的父目录项fseek(file,new_directory[0].start*64+8+5,SEEK_SET);    // 文件指针移动char a[3]={entry.attribute,entry.start,entry.len};fwrite(a,1,3,file); // 目录的保存}return new_directory[0];
}// 更改文件扩展名,简单的寻找+赋值,完成1否则-1
int Alter(FILE* file,char* name,char* extend,struct catalog_entry entry)
{int t;int* p=&t;int a = LookUp(file,name,entry.start,entry.len,p).attribute;if(a==0){// 未找到fprintf(fp,"\n未找到要更改扩展名的文件");return -1;}if(a==1){// 未找到fprintf(fp,"\n不能更改目录的扩展名");return -1;}fseek(file,t+3,SEEK_SET);    // 文件指针移动fwrite(extend,1,2,file); // 目录的保存
}// 更改文件属性,简单的寻找+赋值,完成1否则-1
int Change(FILE* file,char* name,int attribute,struct catalog_entry entry)
{if(attribute<2){fprintf(fp,"\n不被允许的文件属性取值:%d,需要大于等于2",attribute);return -1;}int t;int* p=&t;int a = LookUp(file,name,entry.start,entry.len,p).attribute;if(a==0){// 未找到fprintf(fp,"\n未找到要更改属性的文件");return -1;}if(a==1){// 未找到fprintf(fp,"\n不能更改目录的属性");return -1;}fseek(file,t+5,SEEK_SET);    // 文件指针移动char m[1]={attribute};fwrite(m,1,1,file); // 目录的保存
}// python 调用的打开磁盘文件,返回文件指针
FILE* Openfile()
{file = fopen("disk.txt","r+");  //打开磁盘文件if(file == NULL)    // 磁盘文件不存在{Reset_Disk();// 重建磁盘文件file = fopen("disk.txt","r+");  //打开磁盘文件}return file;
}// python 调用的关闭磁盘文件
void Closefile()
{fclose(file);
}// c输出到文件
void Openfp()
{fp = fopen("output.txt","w");  //打开磁盘文件
}// 关闭输出文件
void Closefp()
{fclose(fp);
}// 索引表
char* Index_Variables()
{return index_variables;
}// 位视图
union bit8* Bitwise_View()
{return bitwise_view;
}// 递归得到目录所有项的列表
void Get_ALL_Entry(FILE* file,struct catalog_entry* entry,int start,int len,int t){if(start==0){ // 空了return;}fseek(file,64*start,SEEK_SET);    // 文件指针移动fread(&entry[t*8],8,8,file);  // 读取Get_ALL_Entry(file,entry,index_variables[start],len-1,t+1);
}// 得到目录所有非空项的列表
void Get_Entry(FILE* file,struct catalog_entry* entry,int start,int len){struct catalog_entry directory[len*8];Get_ALL_Entry(file,directory,start,len,0);int i,j;j=0;for(i=0;i<len*8;i++){if(directory[i].attribute != 0){entry[j]=directory[i];j++;}}
}/*
int main()
{file = fopen("disk.txt","r+");  //打开磁盘文件if(file == NULL)    // 磁盘文件不存在{Reset_Disk();// 重建磁盘文件}file = fopen("disk.txt","r+");  //打开磁盘文件{int i,j;int t;int *p=&t;Read_Start(file);// 读取位视图和索引表struct catalog_entry entry[8];fseek(file,64*2,SEEK_SET);    // 文件指针移动fread(entry,8,8,file);// 读取char name[3]={'a','\0','\0'};char name1[3]={'b','\0','\0'};char extend[2]={'x','y'};char data[500]={0};int len = 65;for(i=0;i<len;i++){data[i] = 'o';}data[len] = '\0';len = strlen(data);//Create(file,name1,extend,entry[0],2);// 保存//Delete(file,name,entry[0]);//删除//Catalog_Organization(file,entry[0]);//整理//Makdir(file,name,entry[0]);//建立目录//Deldir(file,name,entry[0]);//删除目录//Edit(file,entry[0],name1,data,len);// 修改文件//Copy(file,LookUp(file,name1,2,1,p),LookUp(file,name,2,1,p));// 拷贝文件//Create(file,name1,extend,entry[0],2);// 保存//Makdir(file,name,entry[0]);//建立目录//Edit(file,entry[0],name1,data,len);// 修改文件//Move(file,entry[0],name1,LookUp(file,name,2,1,p));// 拷贝文件Change(file,name1,3,entry[0]);//Copy(file,LookUp(file,name1,2,1,p),LookUp(file,name,2,1,p));// 拷贝文件//Delete(file,name1,entry[0]);//删除//Deldir(file,name,entry[0]);//删除目录Printf_Entry(LookUp(file,name,2,1,p));//查找Type(file,2,1); // 输出根目录Type(file,4,1);Printf_Bitwise_View();  // 输出位视图Printf_Index_variables();   // 输出索引表}fclose(file);file = NULL;return 0;
}
*/
// gcc Operating_System_C.c -shared -o Operating_System_C.dll

python语言部分

需要四张图片,

文件夹图标.png

可执行文件.png

空文件夹.png

文本文件.png

不想要图片了删除代码中的读取文件

None_directory_image = tk.PhotoImage(file="空文件夹.png")  # 空文件夹图标
directory_image = tk.PhotoImage(file="文件夹图标.png")  # 文件夹图标
text_image = tk.PhotoImage(file="文本文件.png")  # 文本文件图标
executable_image = tk.PhotoImage(file="可执行文件.png")  # 可执行文件图标

Establish_Current_Directory_Bar的判断

if len(item[i]) > 1:  # 是目录if len(item[i][1]) > 0:now_image = directory_image  # 文件夹else:now_image = None_directory_image  # 空文件夹
elif item[i][0].extend == b'e':  # 是可执行文件now_image = executable_image
else:now_image = text_image  # 是文本文件

以及Establish_Current_Directory_Bar的使用(删除这个别忘了右括号不能删)

image=now_image)
import ctypes  # 用来调用c
import re  # 正则匹配用
import sys  # 输出重定向
import tkinter as tk  # gui用
import tkinter.messagebox  # 弹出来的对话框
import tkinter.filedialog  # 文件相关窗口
from tkinter import ttk  # 仅仅用到了树视图
import time  # 记录时间和线程睡眠用
from threading import Thread  # 进程# 用于重定向输出到文本框
class Redirect:# Redirect(文本控件)def __init__(self, text):  # 构造函数self.text = text# 备份self.stdout = sys.stdoutself.stderr = sys.stderrdef write(self, data):self.text.insert('end', data)self.text.see(tk.END)self.text.update()  # 更新显示的文本def restoreStd(self):# 还原sys.stdout = self.stdoutsys.stderr = self.stdout# 读取C的输出
def Out_Put_C():try:# 读取文件内容with open('output.txt', 'r', encoding='utf-8') as f:print(f.read())except FileNotFoundError:print('文件 output.txt 不存在')# 目录项结构体
class catalog_Entry(ctypes.Structure):_fields_ = [("name", ctypes.c_char * 3),("extend", ctypes.c_char * 2),("attribute", ctypes.c_ubyte),("start", ctypes.c_ubyte),("len", ctypes.c_ubyte), ]# 从byte中取第bit位(从右数)
def Byte_Bit(byte, bit):# 原理:# 11001000 & 00001000if byte & (1 << bit):return 1else:return 0# 创建文件编辑窗口
def File_Editing(entry, directory, name):def Close_Callback():  # 关闭的回调函数user_interface_bar.input_entry['state'] = 'normal'  # 启用用户输入edit_window.destroy()  # 销毁窗口def Save_File():  # 保存+关闭content = edit_window.text.get('1.0', 'end-1c')  # 读取全部文本,不加-1末尾会多一个回车data = ctypes.c_char_p(content.encode())new_data = ctypes.cast(data, ctypes.POINTER(ctypes.c_char * len(content))).contentsOperating_System_C.Edit(file, entry, name, new_data, ctypes.c_int(len(content)))# 保存数据Change_Disk_Bar()  # 位视图索引表更新Change_Current_Directory_Bar()  # 目录更新Close_Callback()# 已经判断过是文件了# Operating_System_C.Read_File(file,entry,char* data) # 读取文件内容edit_window = tk.Toplevel(main_window)  # 生成编辑窗口edit_window.title("文件编辑")edit_window.geometry("400x200")user_interface_bar.input_entry['state'] = 'disabled'  # 禁用用户输入edit_window.protocol("WM_DELETE_WINDOW", Close_Callback)  # 绑定关闭回调edit_window.scrollbar = tk.Scrollbar(edit_window, orient=tk.VERTICAL)  # 滚动条yedit_window.text = tk.Text(edit_window, yscrollcommand=edit_window.scrollbar.set, )  # 用户文本框edit_window.text.bind("<Control-s>", lambda g: Save_File())  # Ctrl+s回调data = (ctypes.c_char * (directory.len * 64 + 1))()Operating_System_C.Read_File(file, directory, data)  # 读取文件edit_window.text.insert('end', data.value.decode())edit_window.scrollbar.pack(side=tk.RIGHT, fill=tk.Y)  # 靠右,拉满yedit_window.scrollbar.config(command=edit_window.text.yview)edit_window.text.pack(fill=tk.BOTH, expand=1)menubar = tk.Menu(edit_window)  # 菜单栏# 文件菜单是菜单栏的子菜单,且不能窗口化submenu_file = tk.Menu(menubar, tearoff=False)submenu_file.add_command(label='保存文件', command=Save_File)submenu_file.add_separator()  # 分割线submenu_file.add_command(label='关闭', command=Close_Callback)  # command为要调用的函数menubar.add_cascade(label='文件', menu=submenu_file)  # 菜单添加文件子菜单项edit_window.config(menu=menubar)  # 生成菜单栏,窗口与菜单关联pass# 创建文件运行窗口
def Run_File(entry, way, directory):def Close_Callback():  # 关闭的回调函数run_window.destroy()  # 销毁窗口def Save_X(x, directory):# 从后往前按最后一个/分割一次route = directory.rsplit('/', 1)if not len(route) == 2:  # 如果长度不是2tkinter.messagebox.showerror('程序运行发生错误', "输出路径'" + directory + "'错误\n")Close_Callback()returnentry = Get_Route(route[0])  # 目录dir = Get_Route(directory)  # 文件的目录项if not entry.attribute == 1 or dir.attribute < 2:tkinter.messagebox.showerror('程序运行发生错误', "输出路径'" + directory + "'错误\n", )Close_Callback()returnname = (ctypes.c_char * 3)()# 将Python字符串赋值给数组String_C_char(name, route[1], 3)content = way + '  x=' + str(x.get())out_str = ctypes.c_char_p(content.encode())out_str = ctypes.cast(out_str, ctypes.POINTER(ctypes.c_char * len(content))).contentsOperating_System_C.Edit(file, entry, name, out_str, ctypes.c_int(len(content)))# 保存数据Change_Disk_Bar()  # 位视图索引表更新Change_Current_Directory_Bar()  # 目录更新tkinter.messagebox.showinfo("文件保存完成", "代码的输出已经保存到" + way, )Close_Callback()def Get_Row(current_row):  # 返回下一行文本try:row_str = data_bar.text.get(f"{current_row[0]}.0", f"{current_row[0]}.end")  # 获得一行文本current_row[0] += 1  # 下次找下一行current_instruction.set(row_str)  # 文本赋值except:row_str = ""return row_str  # 返回文本def Execute(str):# 正则表达式,来匹配输入是不是要求的五种之一pattern = [r'^x=(-?\d+);', r'^x([+]){2};', r'^x([-]){2};', r"!([ABC])(\d+|x);", r'^end\.$']match = re.match(pattern[0], str)if match:  # x=?num = int(match.group(1))  # 得到数字部分x.set(num)  # 赋值return [0]elif re.match(pattern[1], str):  # x++x.set(x.get() + 1)  # 赋值return [1]elif re.match(pattern[2], str):  # x--x.set(x.get() - 1)  # 赋值return [2]else:match = re.match(pattern[3], str)if match:  # !??letter = match.group(1)number = match.group(2)number1 = re.match(r"^\d+$", number)  # 判断是不是正整数if number1:return [3, letter, int(number)]  # 是正整数else:return [3, letter, x.get()]  # 不是正整数elif re.match(pattern[4], str):  # end.return [4]else:  # 未匹配return [-1]def working():while 1:row_str = Get_Row(current_row)if row_str == "" or row_str is None:breakmate = Execute(row_str)if mate[0] == -1:# 报错+回调关闭tkinter.messagebox.showerror('程序运行发生错误', "代码'" + row_str + "'匹配错误\n", )Close_Callback()breakif mate[0] == 3:  # 使用机子并等待使用完毕for i in range(101):  # 相当于100秒if i == 100:# 报错+回调关闭tkinter.messagebox.showerror('程序运行等待超时', "等待" + str(mate[1]) + "超时", )Close_Callback()breakif device[str(mate[1])].get() == 0:  # 没有被占用# 使用设备using_devices = Thread(target=lambda d=mate[1], t=mate[2]: Change_device_time(d, t))device[str(mate[1])].set(mate[2])using_devices.start()using_devices.join()  # 等待运行结束操作系统阻塞展示breaktime.sleep(1)if mate[0] == 4:  # 运行完毕Save_X(x, directory)time.sleep(1)current_row = [1]run_window = tk.Toplevel(main_window)  # 生成运行窗口========================================================run_window.title("文件运行")run_window.geometry("600x400")run_window.rowconfigure(0, weight=1, minsize=100)  # row为0,缩放比为1run_window.rowconfigure(1, weight=1, minsize=100)  # row为1,缩放比为1run_window.rowconfigure(2, weight=1, minsize=100)  # row为2,缩放比为1run_window.columnconfigure(0, weight=1, minsize=300)  # column为0,缩放比为1run_window.columnconfigure(1, weight=1, minsize=200)  # column为1,缩放比为1data_bar = tk.LabelFrame(run_window, text="文件已加载")  # 文件显示框架========================================data_bar.grid(row=0, column=0, rowspan=3)  # 三行data_bar.scrollbar = tk.Scrollbar(data_bar, orient=tk.VERTICAL)  # 滚动条ydata_bar.text = tk.Text(data_bar, yscrollcommand=data_bar.scrollbar.set)data_bar.scrollbar.pack(side=tk.RIGHT, fill=tk.Y)  # 靠右,拉满ydata_bar.scrollbar.config(command=data_bar.text.yview)data_bar.text.bind('<Key>', "break")data_bar.text.pack(fill=tk.BOTH)data = (ctypes.c_char * (entry.len * 64 + 1))()Operating_System_C.Read_File(file, entry, data)  # 读取文件data_bar.text.insert('end', data.value.decode())current_instruction_bar = tk.LabelFrame(run_window, text="当前指令")  # 当前指令框架===========================current_instruction_bar.grid(row=0, column=1)current_instruction = tk.StringVar()current_instruction.set("")current_instruction_bar.entry = tk.Entry(current_instruction_bar, exportselection=0, borderwidth=3,textvariable=current_instruction, relief='sunken')  # 当前指令文本框current_instruction_bar.entry.bind('<Key>', "break")current_instruction_bar.entry.pack(fill=tk.BOTH)x_price_bar = tk.LabelFrame(run_window, text="x的值")  # x的值框架============================================x_price_bar.grid(row=1, column=1)x = tk.IntVar()x.set(0)x_price_bar.entry = tk.Entry(x_price_bar, exportselection=0, borderwidth=3,textvariable=x, relief='sunken')  # x的值文本框x_price_bar.entry.bind('<Key>', "break")x_price_bar.entry.pack(fill=tk.BOTH)device_bar = tk.LabelFrame(run_window, text="设备")  # 当前设备框架============================================device_bar.grid(row=2, column=1)lable_A = tk.Label(device_bar, text="A")  # A标签lable_B = tk.Label(device_bar, text="B")  # B标签lable_C = tk.Label(device_bar, text="C")  # C标签device_A = tk.Entry(device_bar, textvariable=device["A"], relief='sunken')  # A的值文本框device_B = tk.Entry(device_bar, textvariable=device["B"], relief='sunken')  # B的值文本框device_C = tk.Entry(device_bar, textvariable=device["C"], relief='sunken')  # C的值文本框device_bar.rowconfigure(0, weight=1, minsize=10)device_bar.rowconfigure(1, weight=1, minsize=10)device_bar.columnconfigure(0, weight=1, minsize=30)  # column为0,缩放比为1device_bar.columnconfigure(1, weight=1, minsize=30)  # column为1,缩放比为1device_bar.columnconfigure(2, weight=1, minsize=30)  # column为2,缩放比为1device_A.bind('<Key>', "break")device_B.bind('<Key>', "break")device_C.bind('<Key>', "break")lable_A.grid(row=0, column=0)lable_B.grid(row=0, column=1)lable_C.grid(row=0, column=2)device_A.grid(row=1, column=0)device_B.grid(row=1, column=1)device_C.grid(row=1, column=2)working()# 根据路径获得目录项
def Get_Route(str_in):entry = catalog_Entry()route = str_in.split("/")  # 按 / 分离if route[0] == '..':  # 父目录entry = user_interface_bar.up_entry.entryelif route[0] == '.':  # 当前目录entry = user_interface_bar.now_entry.entryelse:if not route[0] == 'S':  # 初始不是根目录print("  格式错误,文件路径的表示: S 是根目录,S/A 是根目录下的文件或目录A, S/A/B 是根目录下的目录A中的B")entry.attribute = 0  # 不存在return entryentry.name = b'S'  # 根目录entry.start = 2entry.len = 1entry.attribute = 1t = ctypes.c_int()p = ctypes.pointer(t)for i in route[1:]:data = ctypes.c_char_p(i.encode())name = ctypes.cast(data, ctypes.POINTER(ctypes.c_char * len(i))).contentsentry = Operating_System_C.LookUp(file, name, entry.start, entry.len, p)return entry# 将str前l个给char(python 字符串给C字符串)
def String_C_char(char, str, l):for i in range(l):if i >= len(str):char[i] = b'\0'breakchar[i] = str[i].encode()# 提示
def Prompt(word):print("    输入‘提示’了解更多,输入‘help’了解支持的函数。\n""    左上角是位视图和索引表,颜色是绿色表示未占用,蓝色表示占用,上面的数字表示下一位的索引\n""    右上角是是树形目录结构,修改目录结构后会更新\n""    中间是当前目录和父目录,根目录时相同,可使用 . 和 .. 表示\n""    文件路径的表示: S 是根目录,S/A 是根目录下的文件或目录A, S/A/B 是根目录下的目录A中的B""")# 帮助
def Help(word):print("支持的输入:\n""-----------------------------------------\n""提示\n""help\n""Printf_Bitwise_View-------------输出位视图\n""Printf_Index_variables----------输出索引阵列\n""Printf_Entry 路径----------------输出目录\n""Catalog_Organization 路径--------目录整理\n""Reset_Disk----------------------重建磁盘\n""Create 目录路径 文件名 扩展名------创建文件\n""Delete 路径----------------------删除文件\n""Makdir 目录路径 目录名-------------建立目录\n""Deldir 目录路径-------------------删除目录\n""Type 路径------------------------显示文件\n""Edit 路径------------------------修改文件\n""Copy 文件路径 目标目录路径---------拷贝文件\n""Move 文件路径 目标目录路径---------移动文件或目录\n""Change 文件路径 属性--------------更改文件属性\n""Alter 文件路径 扩展名-------------更改文件扩展名\n""Run 文件路径 结果输出路径----------执行文件\n""CD 路径--------------------------前往目录\n""Release 设备名-------------------强行释放设备\n")# Printf_Bitwise_View-------------输出位视图
def Printf_Bitwise_View(word):if len(word) > 1:print(" ".join(word[1:]), "是多余的参数\n")print("函数用法:Printf_Bitwise_View-------------输出位视图")returnOperating_System_C.Printf_Bitwise_View()# Printf_Index_variables----------输出索引阵列
def Printf_Index_variables(word):if len(word) > 1:print(" ".join(word[1:]), "是多余的参数\n")print("函数用法:Printf_Index_variables----------输出索引阵列")returnOperating_System_C.Printf_Index_variables()# Printf_Entry 路径----------------输出目录
def Printf_Entry(word):if len(word) > 2:print(" ".join(word[2:]), "是多余的参数\n")print("函数用法:Printf_Entry 路径----------------输出目录")returnif len(word) < 2:print("参数过少")print("函数用法:Printf_Entry 路径----------------输出目录")returnentry = Get_Route(word[1])Operating_System_C.Printf_Entry(entry)# Catalog_Organization 路径--------目录整理
def Catalog_Organization(word):if len(word) > 2:print(" ".join(word[2:]), "是多余的参数\n")print("函数用法:Catalog_Organization 路径--------目录整理")returnif len(word) < 2:print("参数过少")print("函数用法:Catalog_Organization 路径--------目录整理")returnentry = Get_Route(word[1])if not entry.attribute == 1:  # 不是目录print("路径不是目录")returnOperating_System_C.Catalog_Organization(file, entry)Change_Disk_Bar()  # 位视图索引表更新Change_Current_Directory_Bar()  # 目录更新# Reset_Disk----------------------重建磁盘
def Reset_Disk(word):if len(word) > 1:print(" ".join(word[1:]), "是多余的参数\n")print("函数用法:Reset_Disk----------------------重建磁盘")returnOperating_System_C.Reset_Disk()Change_Disk_Bar()  # 位视图索引表更新Change_Current_Directory_Bar()  # 目录更新# Create 目录路径 文件名 扩展名------创建文件
def Create(word):if len(word) > 4:print(" ".join(word[4:]), "是多余的参数\n")print("函数用法:Create 目录路径 文件名 扩展名------创建文件")returnif len(word) < 4:print("参数过少")print("函数用法:Create 目录路径 文件名 扩展名------创建文件")returnentry = Get_Route(word[1])if not entry.attribute == 1:print("路径错误")return# 将Python字符串赋值给数组name = (ctypes.c_char * 3)()String_C_char(name, word[2], 3)extend = (ctypes.c_char * 2)()String_C_char(extend, word[3], 2)Operating_System_C.Create(file, name, extend, entry, ctypes.c_char(2))Change_Disk_Bar()  # 位视图索引表更新Change_Current_Directory_Bar()  # 目录更新# Delete 路径----------------------删除文件
def Delete(word):if len(word) > 2:print(" ".join(word[2:]), "是多余的参数\n")print("函数用法:Delete 路径----------------------删除文件")returnif len(word) < 2:print("参数过少")print("函数用法:Delete 路径----------------------删除文件")return# 从后往前按最后一个/分割一次route = word[1].rsplit('/', 1)if not len(route) == 2:  # 如果长度不是2print("路径错误")returnentry = Get_Route(route[0])  # 目录if not entry.attribute == 1:print("路径错误")return# 将Python字符串赋值给数组name = (ctypes.c_char * 3)()String_C_char(name, route[1], 3)# c中会拒绝删除目录Operating_System_C.Delete(file, name, entry)Change_Disk_Bar()  # 位视图索引表更新Change_Current_Directory_Bar()  # 目录更新# Makdir 目录路径 目录名-------------建立目录
def Makdir(word):if len(word) > 3:print(" ".join(word[3:]), "是多余的参数\n")print("函数用法:Makdir 目录路径 目录名-------------建立目录")returnif len(word) < 3:print("参数过少")print("函数用法:Makdir 目录路径 目录名-------------建立目录")returnentry = Get_Route(word[1])if not entry.attribute == 1:print("路径错误")returnname = (ctypes.c_char * 3)()# 将Python字符串赋值给数组String_C_char(name, word[2], 3)Operating_System_C.Makdir(file, name, entry)Change_Disk_Bar()  # 位视图索引表更新Change_Current_Directory_Bar()  # 目录更新# Deldir 目录路径-------------------删除目录
def Deldir(word):if len(word) > 2:print(" ".join(word[2:]), "是多余的参数\n")print("函数用法:Deldir 目录路径-------------------删除目录")returnif len(word) < 2:print("参数过少")print("函数用法:Deldir 目录路径-------------------删除目录")return# 从后往前按最后一个/分割一次route = word[1].rsplit('/', 1)if not len(route) == 2:  # 如果长度不是2print("路径错误")returnentry = Get_Route(route[0])  # 目录if not entry.attribute == 1:print("路径错误")returnname = (ctypes.c_char * 3)()# 将Python字符串赋值给数组String_C_char(name, route[1], 3)Operating_System_C.Deldir(file, name, entry)Change_Disk_Bar()  # 位视图索引表更新Change_Current_Directory_Bar()  # 目录更新# Type 路径------------------------显示文件
def Type(word):if len(word) > 2:print(" ".join(word[2:]), "是多余的参数\n")print("函数用法:Type 路径------------------------显示文件")returnif len(word) < 2:print("参数过少")print("函数用法:Type 路径------------------------显示文件")returnentry = Get_Route(word[1])if not entry.attribute == 1:  # 不是目录print("路径不是目录")returnOperating_System_C.Type(file, entry.start, entry.len)pass# Edit 路径------------------------修改文件
def Edit(word):if len(word) > 2:print(" ".join(word[2:]), "是多余的参数\n")print("函数用法:Edit 路径------------------------修改文件")returnif len(word) < 2:print("参数过少")print("函数用法:Edit 路径------------------------修改文件")return# 从后往前按最后一个/分割一次route = word[1].rsplit('/', 1)if not len(route) == 2:  # 如果长度不是2print("路径错误")returnentry = Get_Route(route[0])  # 目录directory = Get_Route(word[1])  # 文件的目录项if not entry.attribute == 1 or directory.attribute < 2:print("路径错误")returnname = (ctypes.c_char * 3)()# 将Python字符串赋值给数组String_C_char(name, route[1], 3)File_Editing(entry, directory, name)  # 创建文件编辑窗口# Copy 文件路径 目标目录路径---------拷贝文件
def Copy(word):if len(word) > 3:print(" ".join(word[3:]), "是多余的参数\n")print("函数用法:Copy 文件路径 目标目录路径---------拷贝文件")returnif len(word) < 3:print("参数过少")print("函数用法:Copy 文件路径 目标目录路径---------拷贝文件")returndocument = Get_Route(word[1])  # 文件的目录项entry = Get_Route(word[2])  # 目标目录if not entry.attribute == 1:print("路径错误")returnOperating_System_C.Copy(file, document, entry)Change_Disk_Bar()  # 位视图索引表更新Change_Current_Directory_Bar()  # 目录更新# Move 文件路径 目标目录路径---------移动文件或目录
def Move(word):if len(word) > 3:print(" ".join(word[3:]), "是多余的参数\n")print("函数用法:Move 文件路径 目标目录路径---------移动文件或目录")returnif len(word) < 3:print("参数过少")print("函数用法:Move 文件路径 目标目录路径---------移动文件或目录")returnroute = word[1].rsplit('/', 1)if not len(route) == 2:  # 如果长度不是2print("路径错误")returndirectory = Get_Route(route[0])  # 目录if not directory.attribute == 1:print("路径错误")returnname = (ctypes.c_char * 3)()# 将Python字符串赋值给数组String_C_char(name, route[1], 3)entry = Get_Route(word[2])  # 目标目录if not entry.attribute == 1:print("路径错误")returnOperating_System_C.Move(file, directory, name, entry)Change_Disk_Bar()  # 位视图索引表更新Change_Current_Directory_Bar()  # 目录更新# Change 文件路径 属性--------------更改文件属性
def Change(word):if len(word) > 3:print(" ".join(word[3:]), "是多余的参数\n")print("函数用法:Change 文件路径 属性--------------更改文件属性")returnif len(word) < 3:print("参数过少")print("函数用法:Change 文件路径 属性--------------更改文件属性")return# 从后往前按最后一个/分割一次route = word[1].rsplit('/', 1)if not len(route) == 2:  # 如果长度不是2print("路径错误")returnentry = Get_Route(route[0])  # 目录if not entry.attribute == 1:print("路径错误")returnname = (ctypes.c_char * 3)()# 将Python字符串赋值给数组String_C_char(name, route[1], 3)try:attribute = int(word[2])except:print("属性的值存在问题,属性只能是大于1的正整数")returnOperating_System_C.Change(file, name, attribute, entry)Change_Disk_Bar()  # 位视图索引表更新Change_Current_Directory_Bar()  # 目录更新# Alter 文件路径 扩展名-------------更改文件扩展名
def Alter(word):if len(word) > 3:print(" ".join(word[3:]), "是多余的参数\n")print("函数用法:Alter 文件路径 扩展名-------------更改文件扩展名")returnif len(word) < 3:print("参数过少")print("函数用法:Alter 文件路径 扩展名-------------更改文件扩展名")return# 从后往前按最后一个/分割一次route = word[1].rsplit('/', 1)if not len(route) == 2:  # 如果长度不是2print("路径错误")returnentry = Get_Route(route[0])  # 目录if not entry.attribute == 1:print("路径错误")returnname = (ctypes.c_char * 3)()# 将Python字符串赋值给数组String_C_char(name, route[1], 3)extend = (ctypes.c_char * 2)()String_C_char(extend, word[2], 2)Operating_System_C.Alter(file, name, extend, entry)Change_Disk_Bar()  # 位视图索引表更新Change_Current_Directory_Bar()  # 目录更新# Run 文件路径 结果输出路径----------执行文件
def Run(word):if len(word) > 3:print(" ".join(word[2:]), "是多余的参数\n")print("函数用法:Run 文件路径 结果输出路径----------执行文件")returnif len(word) < 3:print("参数过少")print("函数用法:Run 文件路径 结果输出路径----------执行文件")returnentry = Get_Route(word[1])if entry.attribute < 2 or not entry.extend == b'e':  # 不是文件print("不是可执行文件")returndirectory = word[2]# 创建线程run_file_thread = Thread(target=lambda entry=entry, way=word[1], directory=directory: Run_File(entry, way, directory))# 运行文件run_file_thread.start()pass# CD 路径--------------------------前往目录
def CD(word):if len(word) > 2:print(" ".join(word[2:]), "是多余的参数\n")print("函数用法:CD 路径--------------------------前往目录")returnif len(word) < 2:print("参数过少")print("函数用法:CD 路径--------------------------前往目录")returnroute = word[1].split("/")if route[0] == '..':  # 父目录str_in = user_interface_bar.up_entry.get() + word[1][2:]elif route[0] == '.':  # 当前目录str_in = user_interface_bar.now_entry.get() + word[1][1:]else:str_in = word[1]entry = Get_Route(str_in)  # 目标目录if not entry.attribute == 1:print("路径错误")returnroute = str_in.rsplit('/', 1)user_interface_bar.now_entry.set(str_in)user_interface_bar.now_entry.entry = entryuser_interface_bar.up_entry.set(route[0])user_interface_bar.up_entry.entry = Get_Route(route[0])# Release 设备名-------------------释放设备
def Release(word):if len(word) > 2:print(" ".join(word[2:]), "是多余的参数\n")print("函数用法:Release 设备名-------------------强行释放设备")returnif len(word) < 2:print("参数过少")print("函数用法:Release 设备名-------------------强行释放设备")returnif word[1] == 'A' or word[1] == 'B' or word[1] == 'C':device[word[1]].set(0)else:print(word[1], '设备不存在')# 用于线程的设备到时归0
def Change_device_time(d, t):for i in range(t):if device[d].get() <= 0:  # 被强制结束了device[d].set(0)breaktime.sleep(1)  # 睡一下device[d].set(device[d].get() - 1)  # 减一下def Function_Selection(word):if len(word) == 0:  # 没有输入returnif word[0] in user_function:  # 输入的是函数user_function[word[0]](word)else:print(word[0], "不是可行的函数,请使用 help 查询可用函数")# 分析用户输入
def Input_Analysis(user_input):word = user_input.split()  # 按空格分离print('>>>', " ".join(word))  # 输出你的输入Function_Selection(word)  # 按输入选择函数# 输入框回车的执行内容
def Execute(event):user_input = user_interface_bar.input.get()  # 用户输入user_interface_bar.input.set("")  # 清空输入if len(user_input) > 0:if len(old_input[0]) > 20:  # 最多存20条old_input[0].pop()old_input[0].insert(0, user_input[:])old_input[1] = -1Operating_System_C.Openfp()  # c语言打开c的输出文件# 分析用户输入Input_Analysis(user_input)Operating_System_C.Closefp()  # c语言关闭c的输出文件Out_Put_C()  # python读取并输出C的输出passdef Tab_input(event):now_input = user_interface_bar.input.get()  # 获得当前输入now_input = now_input.split()  # 按空格分离if not len(now_input) == 1:  # 不是长度为1,没反应return 'break'matched = []  # 匹配到的键for key in user_function:  # 遍历所有键if key.startswith(now_input[0]):matched.append(key)if len(matched) < 1:return 'break'elif len(matched) == 1:user_interface_bar.input.set(matched[0])  # 赋值# 将插入点设置为最后一个字符的位置user_interface_bar.input_entry.icursor(tk.END)else:print(matched)return 'break'# 按下上键
def Up_input(event):if old_input[1] + 1 >= len(old_input[0]):  # 到头了return "break"  # 已经是最后的了,不动old_input[1] += 1user_interface_bar.input.set(old_input[0][old_input[1]])  # 赋值、# 将插入点设置为最后一个字符的位置user_interface_bar.input_entry.icursor(tk.END)# 按下下键
def Down_input(event):if old_input[1] < 1:return "break"  # 已经是最后的了,不动old_input[1] -= 1user_interface_bar.input.set(old_input[0][old_input[1]])  # 赋值# 将插入点设置为最后一个字符的位置user_interface_bar.input_entry.icursor(tk.END)# 更新磁盘框架的内容
def Change_Disk_Bar():for i in range(8):for j in range(16):disk_bar.index_variables[i * 16 + j].set('[' + str(index_variables[i * 16 + j]) + ']')disk_bar.label[i * 16 + j]['bg'] = 'blue' if Byte_Bit(bitwise_view[(i * 16 + j) // 8],7 - (i * 16 + j) % 8) else 'green',# 生成磁盘框架的内容
def Generate_Disk_Bar():# 128个块,128个标签。for j in range(16):disk_bar.columnconfigure(j, weight=5)  # column为j,缩放比为1for i in range(8):disk_bar.rowconfigure(i, weight=1)  # row为i,缩放比为1for j in range(16):disk_bar.index_variables.append(tk.StringVar())disk_bar.index_variables[i * 16 + j].set('[' + str(index_variables[i * 16 + j]) + ']')# 父窗口, 文本内容关联的变量, fg 文字颜色, bg 背景颜色,borderwidth 边框大小,ridge 边框样式disk_bar.label.append(tk.Label(disk_bar, textvariable=disk_bar.index_variables[i * 16 + j],fg='white', bg='blue' if Byte_Bit(bitwise_view[(i * 16 + j) // 8],7 - (i * 16 + j) % 8) else 'green',borderwidth=5, relief='ridge'))disk_bar.label[i * 16 + j].grid(row=i, column=j, padx=1, pady=1)# 获取当前的目录
def Obtain_Current_Directory_Bar(updict, start, len):directory = (catalog_Entry * (len * 8))()  # 目录大小Operating_System_C.Get_Entry(file, directory, start, len)  # 获取目录for i in range(2, len * 8):  # 不看父目录和当前目录(前两个)if directory[i].attribute == 0:  # 空了breakupdict[directory[i].name] = [directory[i]]if directory[i].attribute == 1:  # 是目录updict[directory[i].name].append({})Obtain_Current_Directory_Bar(updict[directory[i].name][1], directory[i].start, directory[i].len)# 按item建立新树图
def Establish_Current_Directory_Bar(item, uptree):for i in item:if len(item[i]) > 1:  # 是目录if len(item[i][1]) > 0:now_image = directory_image  # 文件夹else:now_image = None_directory_image  # 空文件夹elif item[i][0].extend == b'e':  # 是可执行文件now_image = executable_imageelse:now_image = text_image  # 是文本文件now_tree = current_directory_bar.treeview.insert(uptree, tk.END, text=item[i][0].name,values=(item[i][0].name, item[i][0].extend, item[i][0].attribute,item[i][0].start, item[i][0].len,),image=now_image)if len(item[i]) > 1:  # 长度大于1是目录Establish_Current_Directory_Bar(item[i][1], now_tree)pass# 更新当前目录框架的内容,时间有限,暴力更新,
def Change_Current_Directory_Bar():current_directory_bar.item.clear()  # 空置Obtain_Current_Directory_Bar(current_directory_bar.item, 2, 1)  # 获得当前的数据current_directory_bar.treeview.delete(*current_directory_bar.treeview.get_children())  # 清空之前的所有树图current_directory_bar.treeview.update()  # 刷新显示Establish_Current_Directory_Bar(current_directory_bar.item, "")  # 递归建立新树# 生成当前目录框架的内容
def Generate_Current_Directory_Bar():# 创建style对象style = ttk.Style()# 设置文本大小style.configure("Treeview", font=("Arial", 12), rowheight=30)# 创建滚动条current_directory_bar.scrollbar_x = tk.Scrollbar(current_directory_bar, orient=tk.HORIZONTAL)  # 滚动条xcurrent_directory_bar.scrollbar_y = tk.Scrollbar(current_directory_bar, orient=tk.VERTICAL)  # 滚动条y# 创建树视图,带滚动条,带标签current_directory_bar.treeview = ttk.Treeview(current_directory_bar, show="tree headings", displaycolumns="#all",columns=('name', 'extend', 'attribute', 'start', 'len'),xscrollcommand=current_directory_bar.scrollbar_x.set,yscrollcommand=current_directory_bar.scrollbar_y.set,style="Treeview")# column设定列宽,heading设定标题current_directory_bar.treeview.column("#0", width=100)current_directory_bar.treeview.heading("#0", text="目录")current_directory_bar.treeview.column("name", width=60)current_directory_bar.treeview.heading('name', text="名称")current_directory_bar.treeview.column("extend", width=60)current_directory_bar.treeview.heading('extend', text="扩展名")current_directory_bar.treeview.column("attribute", width=50)current_directory_bar.treeview.heading('attribute', text="属性")current_directory_bar.treeview.column("start", width=50)current_directory_bar.treeview.heading('start', text="起始块")current_directory_bar.treeview.column("len", width=50)current_directory_bar.treeview.heading('len', text="长度")# 将他们显示出来current_directory_bar.scrollbar_x.pack(side=tk.BOTTOM, fill=tk.X)  # 靠下,拉满xcurrent_directory_bar.scrollbar_x.config(command=current_directory_bar.treeview.xview)current_directory_bar.scrollbar_y.pack(side=tk.RIGHT, fill=tk.Y)  # 靠右,拉满ycurrent_directory_bar.scrollbar_y.config(command=current_directory_bar.treeview.yview)# 居中,填充current_directory_bar.treeview.pack(fill=tk.BOTH, expand=1)# 调用更新树图Change_Current_Directory_Bar()# 初始化c的函数返回值
def Initialization_Operating_System_C():# 默认c_int# file 4字节,其他的几个1字节Operating_System_C.Generate_Catalog_Entry.restype = catalog_EntryOperating_System_C.LookUp.restype = catalog_EntryOperating_System_C.Move.restype = catalog_EntryOperating_System_C.Openfile.restype = ctypes.POINTER(ctypes.c_uint)  # 声明函数返回值为指针Operating_System_C.Index_Variables.restype = ctypes.POINTER(ctypes.c_ubyte)Operating_System_C.Bitwise_View.restype = ctypes.POINTER(ctypes.c_ubyte)def Get_Menu(event):try:menu.tk_popup(event.x_root, event.y_root, 0)finally:# 确保在任何情况下都能隐藏菜单menu.grab_release()# 拦截输入
def Intercept_Input(event):if event.keycode != 67 and event.state != 4:  # 67代表复制快捷键,state=4表示按下Ctrl键return "break"  # 如果不是复制快捷键,就拦截事件'''
┏┓┃┫┣┳┻╋━┗┛
┏━━━━━━━━━━┳━━━━━━━━━━┓
┃ 位视图和  ┃  目录内容 ┃
┃  索引表   ┃          ┃
┣━━━━━━━━━━╋━━━━━━━━━━┫
┃  当前目录 ┃ 上级目录  ┃
┣━━━━━━━━━━┻━━━━━━━━━━┫
┃       用户接口       ┃
┗━━━━━━━━━━━━━━━━━━━━━┛
'''# 加载用C写的函数
Operating_System_C = ctypes.cdll.LoadLibrary('./Operating_System_C.dll')
Operating_System_C.Openfp()  # c语言打开c的输出文件
Initialization_Operating_System_C()  # 初始化返回值
file = Operating_System_C.Openfile()  # 读取文件,获得文件指针,没有文件会创建
Operating_System_C.Read_Start(file)  # 读取位视图和索引表
index_variables = Operating_System_C.Index_Variables()  # 获得位视图和索引表的指针
bitwise_view = Operating_System_C.Bitwise_View()
old_input = [[], -1]  # 以前的输入
open("output.txt", 'w').close()  # 清空以前的输入
user_function = {  # 用户函数表"提示": Prompt,"help": Help,"Printf_Bitwise_View": Printf_Bitwise_View,"Printf_Index_variables": Printf_Index_variables,"Printf_Entry": Printf_Entry,"Catalog_Organization": Catalog_Organization,"Reset_Disk": Reset_Disk,"Create": Create,"Delete": Delete,"Makdir": Makdir,"Deldir": Deldir,"Type": Type,"Edit": Edit,"Copy": Copy,"Move": Move,"Change": Change,"Alter": Alter,"Run": Run,"CD": CD,"Release": Release
}
# 主窗口==========================================================================
# 主窗口==========================================================================
main_window = tk.Tk()  # 调用Tk()创建主窗口
main_window.title("操作系统")  # 给主窗口起一个名字
main_window.geometry("1000x800+200+100")  # 大小
# main_window.config(menu=Generate_Menu(main_window))  # 生成菜单栏,窗口与菜单关联
main_window.rowconfigure(0, weight=1, minsize=200)  # row为0,缩放比为1
main_window.rowconfigure(1, weight=1, minsize=200)  # row为1,缩放比为1,最小200
main_window.columnconfigure(1, weight=1)  # column为1,缩放比为1None_directory_image = tk.PhotoImage(file="空文件夹.png")  # 空文件夹图标
directory_image = tk.PhotoImage(file="文件夹图标.png")  # 文件夹图标
text_image = tk.PhotoImage(file="文本文件.png")  # 文本文件图标
executable_image = tk.PhotoImage(file="可执行文件.png")  # 可执行文件图标# 位视图和索引表===================================================================
# 位视图和索引表===================================================================
disk_bar = tk.LabelFrame(main_window, text="磁盘")  # 放左边磁盘的框架
disk_bar.grid(row=0, column=0, sticky="nsew")
disk_bar.index_variables = []  # 128个标签的文本
disk_bar.label = []  # 128个标签列表
Generate_Disk_Bar()  # 生成磁盘框架的内容
# 树型目录结构====================================================================
# 树型目录结构====================================================================
current_directory_bar = tk.LabelFrame(main_window, text="当前目录内容")  # 放右边目录树的框架
current_directory_bar.grid(row=0, column=1, sticky="nsew")
current_directory_bar.treeview = ttk.Treeview()
current_directory_bar.item = {}  # 所有项目字典
Generate_Current_Directory_Bar()  # 生成当前目录框架的内容
# 用户接口=======================================================================
# 用户接口=======================================================================
# 用户接口比较特殊,放在主体中
user_interface_bar = tk.LabelFrame(main_window, text="用户接口")  # 放下边用户接口的框架
user_interface_bar.grid(row=1, column=0, columnspan=2, sticky="nsew")
user_interface_bar.rowconfigure(0, weight=1, minsize=50)  # row为0,缩放比为1
user_interface_bar.rowconfigure(1, weight=2, minsize=150)  # row为1,缩放比为3
user_interface_bar.columnconfigure(0, weight=1)  # column为0,缩放比为1
user_interface_bar.columnconfigure(1, weight=1)  # column为1,缩放比为1
# 当前目录=========================================
user_interface_bar.now_entry_bar = tk.LabelFrame(user_interface_bar, text="当前目录")  # 当前目录
user_interface_bar.now_entry = tk.StringVar()  # 当前目录变量
user_interface_bar.now_entry.set('S')
user_interface_bar.now_entry.entry = catalog_Entry()
user_interface_bar.now_entry.entry.name = b'S'  # 根目录
user_interface_bar.now_entry.entry.start = 2
user_interface_bar.now_entry.entry.len = 1
user_interface_bar.now_entry.entry.attribute = 1
user_interface_bar.now_lable = tk.Label(user_interface_bar.now_entry_bar, textvariable=user_interface_bar.now_entry,bg='white', borderwidth=2, relief='ridge')  # 当前目录标签
# 上级目录=========================================
user_interface_bar.up_entry_bar = tk.LabelFrame(user_interface_bar, text="上级目录")  # 上级目录
user_interface_bar.up_entry = tk.StringVar()  # 上级目录变量
user_interface_bar.up_entry.set('S')
user_interface_bar.up_entry.entry = catalog_Entry()
user_interface_bar.up_entry.entry.name = b'S'  # 根目录
user_interface_bar.up_entry.entry.start = 2
user_interface_bar.up_entry.entry.len = 1
user_interface_bar.up_entry.entry.attribute = 1
user_interface_bar.up_lable = tk.Label(user_interface_bar.up_entry_bar, textvariable=user_interface_bar.up_entry,bg='white', borderwidth=2, relief='ridge')  # 上级目录标签
# 文本控制台=========================================
user_interface_bar.text_bar = tk.LabelFrame(user_interface_bar, text="文本控制台")  # 文本控制台
user_interface_bar.text_bar.rowconfigure(0, weight=1)  # row为0,缩放比为1
user_interface_bar.text_bar.rowconfigure(1, weight=1, minsize=30)  # row为2,缩放比为1
user_interface_bar.text_bar.columnconfigure(0, weight=1)  # column为0,缩放比为1
user_interface_bar.out_bar = tk.LabelFrame(user_interface_bar.text_bar, text="输出框")  # 文本输出框框架
user_interface_bar.scrollbar = tk.Scrollbar(user_interface_bar.out_bar, orient=tk.VERTICAL)  # 滚动条y
# 字体本来想显示一点文字图之类的,但是会错位,就算了
user_interface_bar.output_entry = tk.Text(user_interface_bar.out_bar, font=('Microsoft Yahei UI', '12',),yscrollcommand=user_interface_bar.scrollbar.set)  # 输出文本框本体# 创建右键菜单
menu = tk.Menu(user_interface_bar.output_entry, tearoff=0)
menu.add_command(label="复制", command=lambda: user_interface_bar.output_entry.event_generate("<Control-c>"))
# 绑定右键事件
user_interface_bar.output_entry.bind("<Button-3>", Get_Menu)
user_interface_bar.output_entry.bind('<Key>', Intercept_Input)  # 键盘输入拦截
sys.stdout = Redirect(user_interface_bar.output_entry)  # 重定向输出到输出文本框
user_interface_bar.input = tk.StringVar()  # 用户输入的变量
user_interface_bar.input.set("")
user_interface_bar.input_entry = tk.Entry(user_interface_bar.text_bar, exportselection=0, borderwidth=3,textvariable=user_interface_bar.input, relief='sunken')  # 用户输入文本框
user_interface_bar.input_entry.bind("<Return>",Execute)  # 回车的回调函数
user_interface_bar.input_entry.bind("<Tab>",Tab_input)  # Tab索引
user_interface_bar.input_entry.bind("<Up>", Up_input)  # 代码看看上面的
user_interface_bar.input_entry.bind("<Down>", Down_input)  # 代码看看后面的
# 部件安放====================================================
user_interface_bar.now_entry_bar.grid(row=0, column=0, sticky="nsew")
user_interface_bar.up_entry_bar.grid(row=0, column=1, sticky="nsew")
user_interface_bar.now_lable.pack(fill=tk.BOTH, expand=1)
user_interface_bar.up_lable.pack(fill=tk.BOTH, expand=1)
user_interface_bar.text_bar.grid(row=1, column=0, columnspan=2, sticky="nsew")
user_interface_bar.out_bar.grid(row=0, column=0, sticky="nsew")
user_interface_bar.scrollbar.pack(side=tk.RIGHT, fill=tk.Y)  # 靠右,拉满y
user_interface_bar.output_entry.pack(fill=tk.BOTH)
user_interface_bar.scrollbar.config(command=user_interface_bar.output_entry.yview)
user_interface_bar.input_entry.grid(row=1, column=0, sticky="nsew")
# =========================================
# =========================================
Operating_System_C.Closefp()  # c语言关闭c的输出文件
Out_Put_C()
device = {"A": tk.IntVar(), "B": tk.IntVar(), "C": tk.IntVar()}  # 三个设备
device["A"].set(0)
device["B"].set(0)
device["C"].set(0)
print("欢迎使用i道i操作系统,输入‘提示’了解更多,输入‘help’了解支持的函数。")
main_window.mainloop()  # 开启主循环,让窗口处于显示状态
Operating_System_C.Closefile()  # 关闭文件
sys.stdout.restoreStd()  # 恢复标准输出

运行实例:

这个是加了图片的示例

下面几张是加图片前的示例

现在支持Ctrl+s了,(确实就一行的事情)

程序进程展示

操作系统阻塞展示

简易操作系统:使用Python 做的图形界面 C 做的内核相关推荐

  1. 210811_152958-Gooey实战 | 几行代码转换Python程序为图形界面应用!

    Gooey实战 | 几行代码转换Python程序为图形界面应用! 1.概述 今天发现公众号的一个作者大大用Python写了个小工具, 发现还挺好玩, 而且代码已经分享给大家了.在文章末尾提到还没有为这 ...

  2. python写前端图形界面_如何Tkinter模块编写Python图形界面

    一.为何使用Tkinter而非PyQt 众所周知,在Python中创建图形界面程序有很多种的选择,其中PyQt和wxPython都是很热门的模块包,这些第三方的图形界面模块功能强大.配置丰富,界面美观 ...

  3. 【PySimpleGUI】Python用户交互图形界面开发(3)

    目录 前言 一.通过列表索引获取窗口返回值 二.通过字典的键获取返回值 前言 上一篇文章介绍了窗口关闭,按钮点击以及其他元素事件.[PySimpleGUI]Python用户交互图形界面开发(2) 这篇 ...

  4. python界面设计实例-【Python】Tkinter图形界面设计(GUI)

    简介 作为 Python 开发者,图形用户界面(GUI)开发是必备技能之一.目前,市面上支持 Python 的"GUI 工具包"很多,各有特点,虽然大多数工具包的基础类似,但要学习 ...

  5. 【Python】Tkinter图形界面设计(GUI)

    简介 作为 Python 开发者,图形用户界面(GUI)开发是必备技能之一.目前,市面上支持 Python 的"GUI 工具包"很多,各有特点,虽然大多数工具包的基础类似,但要学习 ...

  6. 神奇!一行代码将Python程序转换为图形界面应用

    Gooey项目支持用一行代码将(几乎)任何Python 2或3控制台程序转换为GUI应用程序. 1.快速开始 请选择以下任一种方式输入命令安装依赖: 1. Windows 环境 打开 Cmd (开始- ...

  7. 计算机网络课程设计--基于TCP协议网上聊天程序--python实现带图形界面--socket--多线程

                                              基于TCP协议网上聊天程序 引言 21世纪是一个以网络为核心的信息时代,要实现信息化,就必须依靠完善的网络.而随着计 ...

  8. python常用的图形界面

    1.Tkinter: python库自带的一个轻量GUI系统,不需要额外安装.没有布局器,想开发一个好看的系统非常复杂,需要反复的调试大小及布局. 2.pyQT: 三方库,需要安装第三方库,gpl协议 ...

  9. 牛逼了!仅需一行代码将Python程序转换为图形界面应用

    Gooey项目支持用一行代码将(几乎)任何Python 2或3控制台程序转换为GUI应用程序. 请选择以下任一种方式输入命令安装依赖: 1. Windows 环境 打开 Cmd (开始-运行-CMD) ...

最新文章

  1. 关于深度学习编译器,这些知识你需要知道
  2. django源码解析一(请求处理流程)
  3. C# WinForm 添加Windows Media Player 控件调试出现未能加载文件或程序集Interop.WMPLib,该怎么解决...
  4. Python 实现微信小程序的用户登录
  5. 查看Linux服务器运行级别命令,linux命令1、如何查看当前的Linux服务器的运行级别?...
  6. vue中Axios网络请求之Vue知识点归纳(十)
  7. 大公司和小公司的比较
  8. ORACLE数据库DDL审计触发器与隐藏参数_system_trig_enabled
  9. mount、umount 挂载卸载命令
  10. 【2021山东大学数字逻辑实验7】异步模8加1计数器
  11. uplift model增益模型相关术语概念名词汇总
  12. 安装完黑苹果之后该做的事情
  13. C++一本通题库1015
  14. fish or cut bait 当机立断
  15. docker ubuntu-18.04 实战系列一
  16. 通过一张照片查对方位置
  17. 外汇交易与实务--外汇交易市场
  18. ieee latex 双栏_IEEE 投稿Latex设置
  19. 一次性修改AD原理图中元器件PCB封装库路径
  20. 用CDN的小伙伴注意了 小心阿里云注销你的备案

热门文章

  1. 什么是自尊心?自尊心对一个人有多重要?优缺点是什么?
  2. 电子手轮 (位置跟随,X轴或Y轴) 200smart、威纶通触摸屏
  3. 古诗词中“草”的意象
  4. cesium和前端gis开发招聘
  5. 使用WebRTC搭建前端视频聊天室系列文章
  6. 网络黑白棋(翻转棋) v2.0 怎么用
  7. 前世的五百次回眸才能换得今生的一次擦肩而过
  8. springCloud-Alibaba
  9. 计算机的普及是把双刃剑的英语作文,科技是把双刃剑考研英语作文
  10. 企业岗位申请表-Word简历可编辑下载