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 = 0
def 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 = 0
def depth(t):
if t is not None:
lDepth = depth(t.left)
rDepth = depth(t.right)
return max(lDepth, rDepth) + 1
else:
return 0
def 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 fore
def 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 + 1
def 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:
pass
def 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 doc
def 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 doc
def 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 I
def ls(doc):
for i in doc:
ino = inode_table[doc[I]]
type = ''
if ino.type == 1:
type = '<dir>'
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)
网友评论