美文网首页
文件管理

文件管理

作者: 阿拉39 | 来源:发表于2018-05-10 22:36 被阅读0次

    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)
    

    相关文章

      网友评论

          本文标题:文件管理

          本文链接:https://www.haomeiwen.com/subject/daxxdftx.html