|
|
# -*- 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)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|