# -*- encoding: utf-8 -*- ''' @File : files_sys_sim.py @License : (C)Copyright 2018-2022 @Modify Time @Author @Version @Desciption ------------ ------- -------- ----------- 2023/8/15 10:41 zart20 1.0 None ''' import copy import random from pprint import pprint ######### 7.1 ################# from typing import List, Union blocks_label_set = set() def get_unique_tag(): # 获取唯一字母标签 for ascii_code in range(65,91): character = chr(ascii_code) if character not in blocks_label_set: blocks_label_set.add(character) return character def initialize_fileblock(block_num, code): # 产生数据块 files = [] for n in range(int(block_num)): files.append(f"{code}{n+1}") if code == "Z": blocks_label_set.clear() return files def initialize_folderitem(): # 产生文件 folder_items = [] for i in range(3): name = f"f{i}" first = random.randint(1,100) block_num = random.randint(1,11) item = [name, first,block_num] folder_items.append(item) return folder_items def initialize_simdisk(): sim_disk = [[0] *10 for _ in range(10)] # 产生 磁盘数据 return sim_disk def initialize_simfat(): sim_fat = [[0] * 10 for _ in range(10)] # 产生 FAT数据 sim_fat[0][0] = 100 return sim_fat ######### 7.2 ################# # 假设一个磁盘块大小为64KB(以字节为单位) BLOCK_SIZE = 64 # 初始化SimFAT表元素长度,为10则是100块磁盘块 NUM_ENTRIES = 10 def count_available_space(sim_fat): for i in range(1, len(sim_fat)): # 构造操作数组的操作 for j in range(1, len(sim_fat)): if random.randint(1,10) > 3: # 模拟40% 概率的填入率, sim_fat[i][j] = random.choice([f"{n:02}" for n in range(100)] + ['FF']) # 给每个位置填入随机块 num_available_blocks = sum(row.count(0) for row in sim_fat) # 统计为0的块 return num_available_blocks * BLOCK_SIZE ######### 7.3 ################# BLOCK_NUM = 7 LAST_BLOCK = "FF" FIRST_BLOCK = 8 # 第一块fat位置 def generate_chain_structure(): sim_fat = ["0"] * BLOCK_NUM # 文件块的大小 used_blocks = {"00", FIRST_BLOCK} # 用于存储已经被占用的块位置,且预置00块和第一块为已占用状态 for i in range(len(sim_fat) - 1): while True: location = random.randint(0, 99) if location not in used_blocks: # 防止已经被占用的快被重新占用 sim_fat[i] = location used_blocks.add(location) break sim_fat[-1] = LAST_BLOCK chain_structure = [] # 链结构 for i, value in enumerate(sim_fat): if i == 0: print(f"SimFAT[{FIRST_BLOCK}] -> {value}") item = {FIRST_BLOCK: value} # 构建链结构 else: print(f"SimFAT[{sim_fat[i-1]}] -> {value}") item = {sim_fat[i-1]: value} # 构建链结构 chain_structure.append(item) return chain_structure if __name__ == "__main__": print(generate_chain_structure()) ######### 7.4 ################# sim_fat_chain = [{'08': '02'}, {'02': '56'}, {'56': '31'}, {'31': '55'}, {'55': '67'}, {'67': '74'}, {'74': 'FF'}] def get_disk_block_order(sim_fat_chain, start_block): disk_order = [start_block] current_block = start_block # 当前块 while current_block != "FF": next_block = None for item in sim_fat_chain: # item是字典 if current_block in item: next_block = item[current_block] # 当前键的值是下一个块的键 break if next_block is None: # 当没有下一个块时退出循环 break disk_order.append(next_block) current_block = next_block # 更新当前块 return disk_order print(get_disk_block_order(sim_fat_chain,FIRST_BLOCK)) ######### 7.5 ################# class Folder: def __init__(self): self.folder_items = [] def insert_folder_item(self, file_name, first_block, num_blocks): # 插入一个目录项 item = { "file_name": file_name, "first_block": first_block, "num_blocks": num_blocks } self.folder_items.append(item) return item def retrieve_folder_item(self, target_name): # 检索一个目录项 for item in self.folder_items: if item["file_name"] == target_name: return item return None def delete_folder_item(self, target_name): # 删除一个目录项 for item in self.folder_items: if item["file_name"] == target_name: self.folder_items.remove(item) return True return False def print_folder_items(self): for item in self.folder_items: print(f"File: {item['file_name']} - First Block: {item['first_block']} - Num Blocks: {item['num_blocks']}") # # 通过第一块磁盘块的位置读取整个fat表 # def read_sim_fat(first_block:int, simfat:list[list[int|str]]): # """通过首块从fat中查找FAT表""" # block_nums = [] # 创建一个空列表来存储块号 # block_nums.append(first_block) # while True: # row = first_block // 10 # clown = first_block % 10 # b_num = simfat[row][clown] # if b_num != "FF": # block_nums.append(b_num) # first_block = b_num # 更新 first_block 以继续查找下一个块 # else: # break # return block_nums # 通过第一块磁盘块的位置读取整个fat表 def read_sim_fat(first_block:int, simfat:List[List[Union[int, str]]]): """通过首块从fat中查找FAT表""" block_nums = [] # 创建一个空列表来存储块号 block_nums.append(first_block) while True: row = first_block // 10 clown = first_block % 10 b_num = simfat[row][clown] if b_num != "FF": block_nums.append(b_num) first_block = b_num # 更新 first_block 以继续查找下一个块 else: break return block_nums # X5 【编程7.14】编制程序:假定文件夹信息丢失,程序会依据FAT表,重新生成文件夹。 fat = [[100, 50, 0, 1, 0, 0, 0, 0, 0, 0], [79, 3, 0, 85, 0, 28, 'FF', 91, 39, 0], [46, 69, 52, 0, 0, 0, 0, 0, 67, 0], [0, 0, 22, 21, 87, 0, 92, 0, 84, 66], [0, 77, 0, 0, 0, 0, 'FF', 0, 0, 0], ['FF', 0, 18, 0, 13, 41, 34, 0, 61, 0], [0, 11, 0, 0, 0, 99, 20, 93, 10, 16], [0, 36, 0, 0, 0, 0, 55, 'FF', 0, 98], [15, 0, 0, 0, 58, 88, 32, 86, 38, 0], [0, 76, 80, 33, 0, 0, 0, 0, 65, 17]] # def restore_folder_by_fat(fat_table:list[list]) -> list: def restore_folder_by_fat(fat_table: List[List[int]]) -> List: fat_table = copy.deepcopy(fat_table) ls = [n for i in fat_table for n in i] folders = [] while "FF" in ls: element = "FF" folder = list() while element in ls: ls.remove(element) for i in range(len(fat_table)): for n in range(len(fat_table[0])): if fat_table[i][n] == element: num = i*10+n folder.insert(0, num) element = num fat_table[i][n] = 0 print(folder, len(folder), folder[0]) folders.append(folder) pprint(fat_table) pprint(fat) return folders # 编程7.15】编制程序:首先借助于操作系统磁盘读取功能或借助于专用软件,读取真实磁盘的第0个扇区形成一个文件。 # 然后编程解析该文件的结构,即:解析0扇区内容并显示。 if __name__ == '__main__': Fileblock = initialize_fileblock(6,get_unique_tag()) # Fileblock = initialize_fileblock() FolderItem = initialize_folderitem() SimDisk = initialize_simdisk() SimFAT = initialize_simfat() fat_spece = count_available_space(SimDisk) restore_folder_by_fat(fat)