文件管理

title: 文件管理
date: 2018-05-10 16:59:37
tags: [OS, python]
categories: 操作系统
目标: 通过python模拟终端下的创建/删除文件/文件夹、显示该路径下内容、切换路径、tree等命令。
【文件管理】该代码模拟的是Unix下的superblock和inode进行外存的分配与回收。

文件管理
文章图片
文件2.JPG inode至少包含如下信息:

  • inode 编号
  • 用来识别文件类型,以及用于 stat C 函数的模式信息
  • 文件的链接数目
  • 属主的 UID
  • 属主的组 ID (GID)
  • 文件的大小
  • 文件所使用的磁盘块的实际数目
  • 最近一次修改的时间
  • 最近一次访问的时间
  • 最近一次更改的时间
代码细节:
  • 包含的命令:
    • ls: 显示当前目录下的所有文件
    • mkdir a: 创建名称为a的目录
    • mk a 1000: 创建名称为a的、大小为1000字节的文件
    • tree: 以树的形式显示当前目录下的文件及目录(对不齐)
    • rm a: 移除名称为a的文件/目录(若目录下不为空则无法删除)
  • 代码中inode包含三个直接索引,一级索引,二级索引和三级索引。
import math import time # block = []# 1已用,-1未用 inode_table = [] # root = [] now = []# 当前路径 # File = {}# key是文件名,value是inode编号,就是inode_table里的索引位置class INode(object):# 每个文件只有一个inode def __init__(self, type): self.id = -1# table中的index self.type = type# 文件是0,目录是1 self.blo = [] self.time = -1 self.size = 0 self.file = {}class SuperBlock(object): def __init__(self): self.table = []# 存block中空的下标 self.unused_inode = -1 self.unused_block = -1 self.used_inode = 0 self.used_block = 0def initial(self, num):# 初始化table sup_tab = self.table self.unused_inode = num self.unused_block = num for i in range(int(math.ceil(num / 10))): sup_tab.append(10) sup_tab.append([10 * i + j for j in range(9)]) sup_tab[-1].append([]) sup_tab = sup_tab[-1][-1]# 左孩子是该路径节点下的文件,右孩子是该结点的同级文件 class Tree(object): def __init__(self, date, num, left=None, right=None): self.inode_num = num self.parent = None self.date = date self.left = left self.right = right self.level = 0def depth(t): if t is not None: lDepth = depth(t.left) rDepth = depth(t.right) return max(lDepth, rDepth) + 1 else: return 0def preorder(t): if t is None: return else: print((t.level)*''+'|', end='') print('---', t.date) preorder(t.left) preorder(t.right)def distribute_block(): # print(sup.table) if sup.table[0] == 1:# 当前只剩一块(存下一组的地址),将此块分出去,存的地址覆盖 fore = sup.table[-1][-1][-1][0] - 1# fore是被分出去的块号 sup.table = sup.table[-1][0] else: fore = sup.table[-1].pop(0) # print(fore) sup.table[0] -= 1 return foredef add_date_block(k, i): fore = distribute_block() k[-1].append(fore) # block[k[0]].append(fore) i.blo.append(fore)def add_index_block(a, i, j): index_block = distribute_block()# 申请新的块作为索引块 fore = distribute_block() k = [fore] for kk in range(j-1): k = list(k) a.append([index_block, k]) # block[index_block] = [fore] i.blo.append(fore)def add_tree(name, id): global now if now.left is None:# 当前路径有其他文件 # print(now.left.date) a = Tree(name, id) now.left = a a.parent = now a.level = now.level + 1 else: last = now n = now.left while n is not None: # print(last, n) last = n n = n.right a = Tree(name, id) last.right = a a.parent = now a.level = now.level + 1def distribute(i): if len(inode) < 3:# 直接 fore = distribute_block() inode.append(fore) i.blo.append(fore) if len(inode) == 3: index_block = distribute_block()# 申请新的块作为索引块 block[index_block] = []# 索引块中储存索引 inode.append([index_block, []])# [1, [2, 3, 4]] elif len(inode) <= 6:# 一级索引 k = inode[-1]# 最后的一个 if len(k[-1]) < 3 or not k[-1]: add_date_block(k, i) else:# 该块已满 add_index_block(inode, i, 1) if len(inode) == 6 and len(inode[-1][-1]) == 3: index_block = distribute_block() inode.append([index_block, []])# [5, #k:[15,[[6,[7,8,9]], #[10, [11, 12, 13]], #kk:[14, [...]]] elif len(inode) <= 9:# 二级索引 if not inode[-1][-1]: index_block = distribute_block() inode[-1][-1] = [[index_block, []]] k = inode[-1][-1] kk = k[-1] # print(k) if len(k) <= 3: # print(kk[-1]) if len(kk[-1]) < 3: add_date_block(kk, i) elif len(kk[-1]) == 3: if len(k) < 3: add_index_block(k, i, 1)else: index_block = distribute_block() inode.append([index_block, []]) add_index_block(inode[-1][-1], i, 0) # print(inode) else:# 当前索引块已满 index_block = distribute_block() inode.append([index_block, []]) add_index_block(inode[-1][-1], i, 0) # print(inode[-1][-1][-1][-1]) if len(inode) == 9 and len(inode[-1][-1][-1][-1]) == 3: index_block = distribute_block() inode.append([index_block, []])# [5, #k:[15,[[6,[7,8,9]], #[10, [11, 12, 13]], #kk:[14, [...]]] elif len(inode) <= 9:# 二级索引 if not inode[-1][-1]: index_block = distribute_block() inode[-1][-1] = [[index_block, []]] k = inode[-1][-1] kk = k[-1] # print(k) if len(k) <= 3: # print(kk[-1]) if len(kk[-1]) < 3: add_date_block(kk, i) elif len(kk[-1]) == 3: if len(k) < 3: add_index_block(k, i, 1)else: index_block = distribute_block() inode.append([index_block, []]) add_index_block(inode[-1][-1], i, 0) # print(inode) else:# 当前索引块已满 index_block = distribute_block() inode.append([index_block, []]) add_index_block(inode[-1][-1], i, 0) # print(inode[-1][-1][-1][-1]) if len(inode) == 9 and len(inode[-1][-1][-1][-1]) == 3: index_block = distribute_block() inode.append([index_block, []]) #[1, [[2, [[3, [4, 5,6], #[7, [8, 9, 10], #[11,[12,13,14]]] #[15,[[...] else:# 三级索引 if not inode[-1][-1]: index_block = distribute_block() inode[-1][-1] = [[index_block, []]] if not inode[-1][-1][-1]: index_block = distribute_block() inode[-1][-1][-1] = [[index_block, []]] if not inode[-1][-1][-1][-1]: index_block = distribute_block() inode[-1][-1][-1][-1] = [[index_block, []]] if not inode[-1][-1][-1][-1][-1]: index_block = distribute_block() inode[-1][-1][-1][-1][-1] = [[index_block, []]]a = inode[-1][-1] k = a[-1] kk = k[-1] kkk = kk[-1] print(a) if len(a) <= 3: if len(kk) <= 3: print('kkk' + str(kkk)) if len(kkk[-1]) < 3 or not kkk[-1]: print(222) add_date_block(kkk, i)elif len(kkk[-1]) == 3: print(111) print(k) # if len(a) < 3: if len(kk) < 3: add_index_block(kk, i, 1) else: index_block = distribute_block() inode[-1][-1].append([index_block, []]) add_index_block(inode[-1][-1][-1][-1], i, 0) # else:else:# k满了 index_block = distribute_block() inode.append([index_block, []]) add_index_block(inode[-1][-1][-1][-1], i, 0) else: passdef create_file(name, length, doc):# doc:当前目录的inode if name not in doc.file: if sup.unused_block >= length:# 如果有足够的空闲的块 t = time.asctime(time.localtime(time.time())) i = INode(0) inode_table.append(i)# 新建的inode加入列表 global inode doc.file[name] = inode_table.index(i) i.id = inode_table.index(i) i.size = length i.time = t for j in range(length): distribute(i) # print(i.blo) add_tree(name, i.id)else: print('没有足够的空间!') else: print('文件已存在!') return docdef create_doc(name, doc): if name not in doc.file: if sup.unused_block >= 1: t = time.asctime(time.localtime(time.time())) i = INode(1) inode_table.append(i) doc.file[name] = inode_table.index(i) i.id = inode_table.index(i) i.size = 1 i.time = t distribute(i) add_tree(name, i.id)else: print('没有足够的空间!') else: print('文件已存在!') return docdef change_doc(name, doc): global inode_table if name != '..': try: blo = doc.file[name]# 该路径所占的inode块号 blo = inode_table[blo]# 当前路径的inode if blo.type == 1:# 说明是路径 global now_spr, now now_spr += '/' + name # print(now.date) if now.left.date == name: now = now.left else: # l = now n = now.left while n is not None: if n.date == name: break # l = n n = n.right if n.date == name: now = n # print(blo.file) return blo else:# 有该名称的文件,但不是目录 print('不存在该路径!') except KeyError: print('不存在该路径!') else: if now.date == 'root': return doc # print(now.date) now = now.parent i = inode_table[now.inode_num] # print(now.inode_num) now_spr = '/'.join(now_spr.split('/')[:-1]) return Idef ls(doc): for i in doc: ino = inode_table[doc[I]] type = '' if ino.type == 1: type = '' print("%10s %8s %10s %5d" % (ino.time, type, i, ino.size))def remove(name, doc): global sup if name in doc.file: blo = doc.file[name]# inode号 blo = inode_table[blo].blo# 所占的块号 if blo.type == 0 or (blo.type == 1 and not blo.file): del doc.file[name] for i in blo: if sup.table[0] != 10: print(sup.table) sup.table[-1].insert(0, i) sup.table[0] += 1 else: print(sup.table) sup.table[0] = 1 sup.table[-1] = [[10, sup.table[-1]]] else: print('无法删除!') else: print('没有该文件!')if __name__ == '__main__': all, block_size = 500000, 1024 num = math.ceil(all / block_size) block = [-1] * int(num) sup = SuperBlock() sup.initial(num) i = INode(1)# 当前目录的inode i.blo = 0 i.size = 1 i.time = time.asctime(time.localtime(time.time())) inode_table.append(i) sup.table[0] -= 1 sup.table[-1].pop(0) block[0] = -2 root = Tree('root', 0) now = root now_spr = 'root' inode = []# while True: command = input(now_spr+'/$ ').split() try: if command[0] == 'mkdir': create_doc(command[1], i) elif command[0] == 'cd': i = change_doc(command[1], i) elif command[0] == 'rm': remove(command[1], i) elif command[0] == 'mk': create_file(command[1], math.ceil(int(command[2])/block_size), i) elif command[0] == 'ls': print(inode) ls(i.file) elif command[0] == 'tree': print(now.level*''+now.date) preorder(now.left) print() else: print('没有该命令!') except Exception: print('没有该命令!') # print(Exception)

    推荐阅读