1、python实现通过初始化操作建立一个模拟外存空间的虚拟磁盘文件的代码具体实现以及操作演示,在该文件中保存目录和文件内容。创建该文件时应创建初始的根目录内容、文件分配表。根目录实为一特殊文件,其开始内容为空,大小为一个块。 2、文件目录项(可以采用FCB格式)应包括类型(目录 or文件)、创建日期、大小、第一个磁盘块块号。 3、显示命令提示符“$”,并根据输入命令完成相应的文件操作: ●MD(创建子目录):创建目录文件,并在父目录文件中增加目录项。 ●RD(删除子目录):搜索所要删除的目录是否为空目录,若是则删除。 ●MK(创建空文件):创建指定大小的文件(如输入命令 “mk test 2000”,表示创建大小为2000字节的test文件),并在父目录中添加文件名称;还应对FAT表进行适当修改。 ●DEL(删除文件):如果所要删除的文件存在,则删除,同时修改父目录内容;还应对FAT表进行适当修改。
时间: 2024-02-03 15:12:32 浏览: 103
以下是一个简单实现模拟外存空间的虚拟磁盘文件的Python代码:
```python
import datetime
# 定义磁盘块大小为 1024B
BLOCK_SIZE = 1024
# 定义文件分配表大小为 1024 个块
FAT_SIZE = 1024
# 定义根目录大小为 1 个块
ROOT_DIR_SIZE = 1
# 初始化虚拟磁盘文件
def init_vdisk_file(filename):
with open(filename, 'wb') as f:
# 初始化文件分配表
fat = [0] * FAT_SIZE
# 初始化根目录
root_dir = []
# 将根目录的初始内容写入第一个块
root_dir_block = bytearray(BLOCK_SIZE)
root_dir_block[:len(root_dir)] = bytearray(root_dir)
f.write(root_dir_block)
# 将文件分配表和根目录写入后续的块
for i in range(FAT_SIZE + ROOT_DIR_SIZE - 1):
f.write(bytearray(BLOCK_SIZE))
f.seek(BLOCK_SIZE)
f.write(bytearray(fat))
# 读取指定块的内容
def read_block(filename, block_num):
with open(filename, 'rb') as f:
f.seek(block_num * BLOCK_SIZE)
return bytearray(f.read(BLOCK_SIZE))
# 写入内容到指定块
def write_block(filename, block_num, block_data):
with open(filename, 'r+b') as f:
f.seek(block_num * BLOCK_SIZE)
f.write(block_data)
# 获取空闲块的块号
def get_free_block(filename):
with open(filename, 'r+b') as f:
fat_block = read_block(filename, 0)
for i, value in enumerate(fat_block):
if value == 0:
fat_block[i] = 1
write_block(filename, 0, fat_block)
return i
raise Exception('No free block available.')
# 创建子目录
def mkdir(filename, parent_dir, dir_name):
# 检查目录名是否已存在
for item in parent_dir:
if item[0] == dir_name:
print(f'{dir_name} already exists.')
return
# 创建目录文件
dir_block = bytearray(BLOCK_SIZE)
write_block(filename, get_free_block(filename), dir_block)
# 添加目录项到父目录
parent_dir.append(('dir', dir_name, datetime.datetime.now(), 1))
# 更新父目录内容
parent_block = read_block(filename, 0)
parent_block[:len(parent_dir)] = bytearray(parent_dir)
write_block(filename, 0, parent_block)
# 删除子目录
def rmdir(filename, parent_dir, dir_name):
# 检查目录是否存在
for i, item in enumerate(parent_dir):
if item[0] == 'dir' and item[1] == dir_name:
# 检查目录是否为空
dir_block = read_block(filename, item[3])
if sum(dir_block) == 0:
# 删除目录文件
fat_block = read_block(filename, 0)
fat_block[item[3]] = 0
write_block(filename, 0, fat_block)
# 删除目录项
del parent_dir[i]
# 更新父目录内容
parent_block = read_block(filename, 0)
parent_block[:len(parent_dir)] = bytearray(parent_dir)
write_block(filename, 0, parent_block)
else:
print(f'{dir_name} is not an empty directory.')
return
print(f'{dir_name} not found.')
# 创建空文件
def mkfile(filename, parent_dir, file_name, size):
# 检查文件名是否已存在
for item in parent_dir:
if item[0] == 'file' and item[1] == file_name:
print(f'{file_name} already exists.')
return
# 创建文件块
file_block = bytearray(size)
write_block(filename, get_free_block(filename), file_block)
# 添加文件项到父目录
parent_dir.append(('file', file_name, datetime.datetime.now(), len(file_block) // BLOCK_SIZE))
# 更新父目录内容
parent_block = read_block(filename, 0)
parent_block[:len(parent_dir)] = bytearray(parent_dir)
write_block(filename, 0, parent_block)
# 删除文件
def delfile(filename, parent_dir, file_name):
# 检查文件是否存在
for i, item in enumerate(parent_dir):
if item[0] == 'file' and item[1] == file_name:
# 删除文件块
fat_block = read_block(filename, 0)
for j in range(item[3]):
fat_block[item[2] + j] = 0
write_block(filename, 0, fat_block)
# 删除文件项
del parent_dir[i]
# 更新父目录内容
parent_block = read_block(filename, 0)
parent_block[:len(parent_dir)] = bytearray(parent_dir)
write_block(filename, 0, parent_block)
return
print(f'{file_name} not found.')
# 命令行界面
def cmd_interface():
filename = 'vdisk.bin'
init_vdisk_file(filename)
while True:
path = []
dir_block = read_block(filename, 0)
dir_items = dir_block[:len(dir_block)].split(b'\x00')
while True:
# 显示当前路径
print('$', '/'.join(path), end=' ')
# 获取用户输入
command = input().strip().lower()
if command == '':
continue
elif command == 'exit':
return
elif command == 'ls':
# 列出当前目录的文件和子目录
for item in dir_items:
if item:
item_type, item_name, item_time, item_size = item.split(b',')
if item_type == b'dir':
print(f'{item_name.decode()} <DIR> {datetime.datetime.fromisoformat(item_time.decode()):%Y/%m/%d %H:%M:%S}')
else:
print(f'{item_name.decode()} {int(item_size) * BLOCK_SIZE}B {datetime.datetime.fromisoformat(item_time.decode()):%Y/%m/%d %H:%M:%S}')
elif command.startswith('cd '):
# 进入子目录
dir_name = command[3:]
for item in dir_items:
if item:
item_type, item_name, item_time, item_size = item.split(b',')
if item_type == b'dir' and item_name == dir_name.encode():
path.append(dir_name)
dir_block = read_block(filename, int(item_size))
dir_items = dir_block[:len(dir_block)].split(b'\x00')
break
else:
print(f'{dir_name} not found.')
elif command.startswith('md '):
# 创建子目录
dir_name = command[3:]
mkdir(filename, dir_items, dir_name)
elif command.startswith('rd '):
# 删除子目录
dir_name = command[3:]
rmdir(filename, dir_items, dir_name)
elif command.startswith('mk '):
# 创建空文件
file_name, file_size = command[3:].split()
file_size = int(file_size)
mkfile(filename, dir_items, file_name, file_size)
elif command.startswith('del '):
# 删除文件
file_name = command[4:]
delfile(filename, dir_items, file_name)
else:
print('Invalid command.')
```
运行 `cmd_interface()` 函数即可进入命令行界面。例如,输入 `mk test 2000` 可以创建一个大小为 2000B 的文件名为 `test`。
阅读全文