1、通过初始化操作建立一个模拟外存空间的虚拟磁盘文件,在该文件中保存目录和文件内容。创建该文件时应创建初始的根目录内容、文件分配表。根目录实为一特殊文件,其开始内容为空,大小为一个块。 2、文件目录项(可以采用FCB格式)应包括类型(目录 or文件)、创建日期、大小、第一个磁盘块块号。 3、显示命令提示符“$”,并根据输入命令完成相应的文件操作: ●MD(创建子目录):创建目录文件,并在父目录文件中增加目录项。 ●RD(删除子目录):搜索所要删除的目录是否为空目录,若是则删除。 ●MK(创建空文件):创建指定大小的文件(如输入命令 “mk test 2000”,表示创建大小为2000字节的test文件),并在父目录中添加文件名称;还应对FAT表进行适当修改。 ●DEL(删除文件):如果所要删除的文件存在,则删除,同时修改父目录内容;还应对FAT表进行适当修改。Python写
时间: 2023-12-14 08:36:43 浏览: 186
以下是一个Python实现的简单文件系统,代码中包含了创建目录、删除目录、创建文件、删除文件等基本操作。注意,这是一个非常简单的示例,只能作为学习和参考使用。
```python
import os
import time
# 定义常量
BLOCK_SIZE = 512 # 磁盘块大小
DISK_SIZE = 1024 * 1024 # 磁盘总大小
ROOT_DIR_BLOCK = 0 # 根目录所在磁盘块号
FAT_SIZE = DISK_SIZE // BLOCK_SIZE # FAT表的大小
# 定义目录项类
class DirEntry:
def __init__(self, name, is_dir, size, start_block):
self.name = name # 文件或目录名
self.is_dir = is_dir # 是否为目录
self.size = size # 文件大小
self.start_block = start_block # 起始磁盘块号
self.create_time = time.time() # 创建时间
# 定义文件系统类
class FileSystem:
def __init__(self):
# 初始化磁盘
self.disk = bytearray(DISK_SIZE)
# 初始化FAT表
self.fat = [-1] * FAT_SIZE
# 初始化根目录
self.root_dir = DirEntry("", True, BLOCK_SIZE, ROOT_DIR_BLOCK)
self.write_dir_entry(self.root_dir)
# 写目录项到指定磁盘块
def write_dir_entry(self, entry, block_num=None, offset=0):
if block_num is None:
block_num = entry.start_block
block = self.disk[block_num * BLOCK_SIZE:(block_num + 1) * BLOCK_SIZE]
block[offset:offset+1] = int(entry.is_dir).to_bytes(1, byteorder="big")
block[offset+1:offset+9] = entry.create_time.to_bytes(8, byteorder="big")
block[offset+9:offset+13] = entry.size.to_bytes(4, byteorder="big")
block[offset+13:offset+17] = entry.start_block.to_bytes(4, byteorder="big")
block[offset+17:offset+49] = entry.name.encode("utf-8")
# 从指定磁盘块读取目录项
def read_dir_entry(self, block_num, offset=0):
block = self.disk[block_num * BLOCK_SIZE:(block_num + 1) * BLOCK_SIZE]
is_dir = bool(block[offset])
create_time = int.from_bytes(block[offset+1:offset+9], byteorder="big")
size = int.from_bytes(block[offset+9:offset+13], byteorder="big")
start_block = int.from_bytes(block[offset+13:offset+17], byteorder="big")
name = block[offset+17:offset+49].rstrip(b"\x00").decode("utf-8")
return DirEntry(name, is_dir, size, start_block)
# 分配一个空闲的磁盘块
def allocate_block(self):
for i in range(FAT_SIZE):
if self.fat[i] == -1:
self.fat[i] = 0
return i
raise Exception("磁盘已满,无法分配新块")
# 释放指定磁盘块
def free_block(self, block_num):
self.fat[block_num] = -1
# 在指定目录下创建子目录
def create_dir(self, parent_dir, name):
# 检查是否已存在同名文件或目录
for entry in self.list_dir(parent_dir):
if entry.name == name:
raise Exception("文件或目录已存在")
# 分配一个新的磁盘块作为目录文件
block_num = self.allocate_block()
# 初始化目录项
dir_entry = DirEntry(name, True, BLOCK_SIZE, block_num)
# 写入父目录的文件内容
parent_block_num = parent_dir.start_block
parent_block = self.disk[parent_block_num * BLOCK_SIZE:(parent_block_num + 1) * BLOCK_SIZE]
bytes_written = 0
while bytes_written < parent_dir.size:
entry = self.read_dir_entry(parent_block_num, bytes_written)
bytes_written += 49
if entry.name == "":
self.write_dir_entry(dir_entry, parent_block_num, bytes_written - 49)
parent_dir.size += 49
self.write_dir_entry(parent_dir)
return
# 父目录文件已满,需要分配新块
new_block_num = self.allocate_block()
self.fat[parent_block_num] = new_block_num
self.disk[new_block_num * BLOCK_SIZE:(new_block_num + 1) * BLOCK_SIZE] = bytearray(BLOCK_SIZE)
parent_dir.size += BLOCK_SIZE
self.write_dir_entry(parent_dir)
self.write_dir_entry(dir_entry, new_block_num)
# 删除指定目录
def delete_dir(self, parent_dir, name):
# 搜索目录项
for entry in self.list_dir(parent_dir):
if entry.name == name and entry.is_dir:
# 检查目录是否为空
if not self.is_dir_empty(entry):
raise Exception("目录非空,无法删除")
# 释放目录占用的磁盘块
self.free_block(entry.start_block)
# 从父目录中删除目录项
bytes_written = 0
while bytes_written < parent_dir.size:
cur_entry = self.read_dir_entry(parent_dir.start_block, bytes_written)
bytes_written += 49
if cur_entry.name == name:
parent_dir.size -= 49
self.write_dir_entry(parent_dir)
return
raise Exception("未找到目录项")
raise Exception("目录不存在")
# 在指定目录下创建空文件
def create_file(self, parent_dir, name, size):
# 检查是否已存在同名文件或目录
for entry in self.list_dir(parent_dir):
if entry.name == name:
raise Exception("文件或目录已存在")
# 分配磁盘块
num_blocks = (size + BLOCK_SIZE - 1) // BLOCK_SIZE
blocks = [self.allocate_block() for i in range(num_blocks)]
# 初始化目录项
file_entry = DirEntry(name, False, size, blocks[0])
# 写入父目录的文件内容
parent_block_num = parent_dir.start_block
parent_block = self.disk[parent_block_num * BLOCK_SIZE:(parent_block_num + 1) * BLOCK_SIZE]
bytes_written = 0
while bytes_written < parent_dir.size:
entry = self.read_dir_entry(parent_block_num, bytes_written)
bytes_written += 49
if entry.name == "":
self.write_dir_entry(file_entry, parent_block_num, bytes_written - 49)
parent_dir.size += 49
self.write_dir_entry(parent_dir)
break
else:
# 父目录文件已满,需要分配新块
new_block_num = self.allocate_block()
self.fat[parent_block_num] = new_block_num
self.disk[new_block_num * BLOCK_SIZE:(new_block_num + 1) * BLOCK_SIZE] = bytearray(BLOCK_SIZE)
parent_dir.size += BLOCK_SIZE
self.write_dir_entry(parent_dir)
self.write_dir_entry(file_entry, blocks[0])
# 更新FAT表
for i in range(num_blocks - 1):
self.fat[blocks[i]] = blocks[i+1]
self.fat[blocks[-1]] = -1
# 删除指定文件
def delete_file(self, parent_dir, name):
# 搜索目录项
for entry in self.list_dir(parent_dir):
if entry.name == name and not entry.is_dir:
# 释放文件占用的磁盘块
cur_block = entry.start_block
while cur_block != -1:
next_block = self.fat[cur_block]
self.free_block(cur_block)
cur_block = next_block
# 从父目录中删除目录项
bytes_written = 0
while bytes_written < parent_dir.size:
cur_entry = self.read_dir_entry(parent_dir.start_block, bytes_written)
bytes_written += 49
if cur_entry.name == name:
parent_dir.size -= 49
self.write_dir_entry(parent_dir)
return
raise Exception("未找到文件项")
raise Exception("文件不存在")
# 列出指定目录下的所有文件和子目录
def list_dir(self, parent_dir):
result = []
bytes_written = 0
while bytes_written < parent_dir.size:
entry = self.read_dir_entry(parent_dir.start_block, bytes_written)
bytes_written += 49
if entry.name != "":
result.append(entry)
return result
# 检查目录是否为空
def is_dir_empty(self, dir_entry):
bytes_written = 0
while bytes_written < dir_entry.size:
entry = self.read_dir_entry(dir_entry.start_block, bytes_written)
bytes_written += 49
if entry.name != "":
return False
return True
# 命令行交互
def run_cli(self):
cur_dir = self.root_dir
while True:
prompt = f"{cur_dir.name}>"
cmd = input(prompt).strip()
if cmd == "":
continue
parts = cmd.split()
if parts[0] == "exit":
break
elif parts[0] == "md":
if len(parts) != 2:
print("usage: md <directory>")
else:
try:
self.create_dir(cur_dir, parts[1])
except Exception as e:
print(e)
elif parts[0] == "rd":
if len(parts) != 2:
print("usage: rd <directory>")
else:
try:
self.delete_dir(cur_dir, parts[1])
except Exception as e:
print(e)
elif parts[0] == "mk":
if len(parts) != 3:
print("usage: mk <file> <size>")
else:
try:
size = int(parts[2])
if size <= 0:
raise Exception("文件大小必须为正整数")
self.create_file(cur_dir, parts[1], size)
except ValueError:
print("文件大小必须为正整数")
except Exception as e:
print(e)
elif parts[0] == "del":
if len(parts) != 2:
print("usage: del <file>")
else:
try:
self.delete_file(cur_dir, parts[1])
except Exception as e:
print(e)
elif parts[0] == "cd":
if len(parts) != 2:
print("usage: cd <directory>")
else:
for entry in self.list_dir(cur_dir):
if entry.name == parts[1] and entry.is_dir:
cur_dir = self.read_dir_entry(entry.start_block)
break
else:
print("目录不存在")
elif parts[0] == "dir":
entries = self.list_dir(cur_dir)
for entry in entries:
if entry.is_dir:
print(f"{entry.create_time}\t<DIR>\t{entry.name}")
else:
print(f"{entry.create_time}\t{entry.size}\t{entry.name}")
else:
print(f"无法识别的命令: {parts[0]}")
if __name__ == "__main__":
fs = FileSystem()
fs.run_cli()
```
阅读全文