You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

231 lines
7.0 KiB

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

# -*- 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 #################
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 file_fat_mapping(Fileblock):
pass
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)]
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
# 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:
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())
restore_folder_by_fat(fat)