使用python完成操作系统实验 文件管理通过初始化操作建立一个模拟外存空间的虚拟磁盘文件,在该文件中保存目录和文件内容。创建该文件时应创建初始的根目录内容、文件分配表。根目录实为一特殊文件,其开始内容为空,大小为一个块。 2、文件目录项(可以采用FCB格式)应包括类型(目录 or文件)、创建日期、大小、第一个磁盘块块号。 3、显示命令提示符“$”,并根据输入命令完成相应的文件操作:创建目录、删除目录、创建文件、删除文件
时间: 2023-12-16 10:02:40 浏览: 77
,显示目录、进入目录、返回上级目录、读取文件、写入文件、退出系统。
以下是一个简单的 Python 实现:
``` python
import datetime
# 定义常量
BLOCK_SIZE = 512 # 块大小
DISK_SIZE = 1024*1024*100 # 磁盘大小,100MB
ROOT_DIR_BLOCK_NUM = 0 # 根目录块号
DIR_ENTRY_SIZE = 64 # 目录项大小,64字节
MAX_FILE_SIZE = 1024*1024 # 最大文件大小,1MB
# 初始化磁盘文件
disk_file = open('virtual_disk', 'wb')
disk_file.seek(DISK_SIZE-1)
disk_file.write(b'\x00')
disk_file.close()
# 初始化根目录块
root_dir_block = bytearray(BLOCK_SIZE)
dir_entry = bytearray(DIR_ENTRY_SIZE)
dir_entry[0] = 1 # 类型为目录,1代表目录,0代表文件
dir_entry[1:9] = bytes(datetime.datetime.now().strftime('%Y%m%d'), 'utf-8') # 创建日期
dir_entry[9:13] = int.to_bytes(0, 4, 'little') # 大小为0
dir_entry[13:17] = int.to_bytes(ROOT_DIR_BLOCK_NUM, 4, 'little') # 第一个磁盘块块号
root_dir_block[0:DIR_ENTRY_SIZE] = dir_entry
disk_file = open('virtual_disk', 'rb+')
disk_file.seek(ROOT_DIR_BLOCK_NUM*BLOCK_SIZE)
disk_file.write(root_dir_block)
# 初始化文件分配表
fat = [-1] * (DISK_SIZE // BLOCK_SIZE)
fat[ROOT_DIR_BLOCK_NUM] = 0
# 显示命令提示符
current_dir_block_num = ROOT_DIR_BLOCK_NUM
while True:
command = input('$ ')
if command.startswith('mkdir '):
# 创建目录
dir_name = command[6:]
dir_entry = bytearray(DIR_ENTRY_SIZE)
dir_entry[0] = 1 # 类型为目录
dir_entry[1:9] = bytes(datetime.datetime.now().strftime('%Y%m%d'), 'utf-8') # 创建日期
dir_entry[9:13] = int.to_bytes(0, 4, 'little') # 大小为0
# 查找空闲块
for i in range(len(fat)):
if fat[i] == -1:
fat[i] = 0
dir_entry[13:17] = int.to_bytes(i, 4, 'little') # 第一个磁盘块块号
break
else:
print('磁盘已满,无法创建目录')
continue
# 写入目录项到当前目录块
current_dir_block = disk_file.read(BLOCK_SIZE)
current_dir_block[current_dir_block.find(b'\x00'):current_dir_block.find(b'\x00')+DIR_ENTRY_SIZE] = dir_entry
disk_file.seek(current_dir_block_num*BLOCK_SIZE)
disk_file.write(current_dir_block)
elif command.startswith('rmdir '):
# 删除目录
dir_name = command[6:]
current_dir_block = disk_file.read(BLOCK_SIZE)
dir_entry = current_dir_block[current_dir_block.find(bytes(dir_name, 'utf-8')):current_dir_block.find(bytes(dir_name, 'utf-8'))+DIR_ENTRY_SIZE]
if not dir_entry:
print('目录不存在')
continue
if dir_entry[0] != 1:
print('不是目录')
continue
if dir_entry[9:13] != int.to_bytes(0, 4, 'little'):
print('目录不为空')
continue
fat[int.from_bytes(dir_entry[13:17], 'little')] = -1
current_dir_block[current_dir_block.find(bytes(dir_name, 'utf-8')):current_dir_block.find(bytes(dir_name, 'utf-8'))+DIR_ENTRY_SIZE] = b'\x00'*DIR_ENTRY_SIZE
disk_file.seek(current_dir_block_num*BLOCK_SIZE)
disk_file.write(current_dir_block)
elif command.startswith('touch '):
# 创建文件
file_name = command[6:]
file_entry = bytearray(DIR_ENTRY_SIZE)
file_entry[0] = 0 # 类型为文件
file_entry[1:9] = bytes(datetime.datetime.now().strftime('%Y%m%d'), 'utf-8') # 创建日期
file_entry[9:13] = int.to_bytes(0, 4, 'little') # 大小为0
# 查找空闲块
for i in range(len(fat)):
if fat[i] == -1:
fat[i] = 0
file_entry[13:17] = int.to_bytes(i, 4, 'little') # 第一个磁盘块块号
break
else:
print('磁盘已满,无法创建文件')
continue
# 写入目录项到当前目录块
current_dir_block = disk_file.read(BLOCK_SIZE)
current_dir_block[current_dir_block.find(b'\x00'):current_dir_block.find(b'\x00')+DIR_ENTRY_SIZE] = file_entry
disk_file.seek(current_dir_block_num*BLOCK_SIZE)
disk_file.write(current_dir_block)
elif command.startswith('rm '):
# 删除文件
file_name = command[3:]
current_dir_block = disk_file.read(BLOCK_SIZE)
file_entry = current_dir_block[current_dir_block.find(bytes(file_name, 'utf-8')):current_dir_block.find(bytes(file_name, 'utf-8'))+DIR_ENTRY_SIZE]
if not file_entry:
print('文件不存在')
continue
if file_entry[0] != 0:
print('不是文件')
continue
fat[int.from_bytes(file_entry[13:17], 'little')] = -1
current_dir_block[current_dir_block.find(bytes(file_name, 'utf-8')):current_dir_block.find(bytes(file_name, 'utf-8'))+DIR_ENTRY_SIZE] = b'\x00'*DIR_ENTRY_SIZE
disk_file.seek(current_dir_block_num*BLOCK_SIZE)
disk_file.write(current_dir_block)
elif command == 'ls':
# 显示目录内容
current_dir_block = disk_file.read(BLOCK_SIZE)
for i in range(0, BLOCK_SIZE, DIR_ENTRY_SIZE):
dir_entry = current_dir_block[i:i+DIR_ENTRY_SIZE]
if dir_entry[0] == 0:
print('F', dir_entry[1:9].decode(), int.from_bytes(dir_entry[9:13], 'little'))
elif dir_entry[0] == 1:
print('D', dir_entry[1:9].decode())
elif command.startswith('cd '):
# 进入目录
dir_name = command[3:]
current_dir_block = disk_file.read(BLOCK_SIZE)
dir_entry = current_dir_block[current_dir_block.find(bytes(dir_name, 'utf-8')):current_dir_block.find(bytes(dir_name, 'utf-8'))+DIR_ENTRY_SIZE]
if not dir_entry:
print('目录不存在')
continue
if dir_entry[0] != 1:
print('不是目录')
continue
current_dir_block_num = int.from_bytes(dir_entry[13:17], 'little')
elif command == 'cd..':
# 返回上级目录
if current_dir_block_num == ROOT_DIR_BLOCK_NUM:
print('已经是根目录')
continue
current_dir_block_num = ROOT_DIR_BLOCK_NUM
elif command.startswith('cat '):
# 读取文件
file_name = command[4:]
current_dir_block = disk_file.read(BLOCK_SIZE)
file_entry = current_dir_block[current_dir_block.find(bytes(file_name, 'utf-8')):current_dir_block.find(bytes(file_name, 'utf-8'))+DIR_ENTRY_SIZE]
if not file_entry:
print('文件不存在')
continue
if file_entry[0] != 0:
print('不是文件')
continue
file_block_num = int.from_bytes(file_entry[13:17], 'little')
file_size = int.from_bytes(file_entry[9:13], 'little')
file_content = bytearray()
while file_block_num != -1:
file_block = disk_file.read(BLOCK_SIZE)
file_content += file_block
file_block_num = fat[file_block_num]
print(file_content[:file_size].decode())
elif command.startswith('echo '):
# 写入文件
file_name, content = command[5:].split('>')
file_name = file_name.strip()
content = content.strip()
current_dir_block = disk_file.read(BLOCK_SIZE)
file_entry = current_dir_block[current_dir_block.find(bytes(file_name, 'utf-8')):current_dir_block.find(bytes(file_name, 'utf-8'))+DIR_ENTRY_SIZE]
if not file_entry:
print('文件不存在')
continue
if file_entry[0] != 0:
print('不是文件')
continue
file_block_num = int.from_bytes(file_entry[13:17], 'little')
if len(content) > MAX_FILE_SIZE:
print('文件太大')
continue
i = 0
while file_block_num != -1 and i < len(content):
file_block = bytearray(BLOCK_SIZE)
file_block[:len(content[i:i+BLOCK_SIZE])] = bytes(content[i:i+BLOCK_SIZE], 'utf-8')
disk_file.seek(file_block_num*BLOCK_SIZE)
disk_file.write(file_block)
fat[file_block_num] = 0
file_block_num = fat[file_block_num]
i += BLOCK_SIZE
if i < len(content):
# 分配新块
new_block_num = -1
for i in range(len(fat)):
if fat[i] == -1:
fat[i] = 0
new_block_num = i
break
else:
print('磁盘已满,无法写入文件')
continue
# 写入文件内容
j = 0
while j < len(content[i:i+BLOCK_SIZE]):
file_block = bytearray(BLOCK_SIZE)
file_block[:len(content[i+j:i+j+BLOCK_SIZE])] = bytes(content[i+j:i+j+BLOCK_SIZE], 'utf-8')
disk_file.seek(new_block_num*BLOCK_SIZE)
disk_file.write(file_block)
fat[new_block_num] = 0
new_block_num = fat[new_block_num]
j += BLOCK_SIZE
# 更新文件目录项
file_entry[9:13] = int.to_bytes(i+j, 4, 'little')
file_entry[13:17] = int.to_bytes(new_block_num, 4, 'little')
current_dir_block[current_dir_block.find(bytes(file_name, 'utf-8')):current_dir_block.find(bytes(file_name, 'utf-8'))+DIR_ENTRY_SIZE] = file_entry
disk_file.seek(current_dir_block_num*BLOCK_SIZE)
disk_file.write(current_dir_block)
elif command == 'exit':
# 退出系统
break
else:
print('无效命令')
```
需要注意的是,这只是一个简单的实现,还有很多细节需要处理。比如,如果目录和文件名中包含空格怎么办?如果目录不止一个块怎么处理?如果文件大小超过一个块怎么处理?如果磁盘已满怎么处理?等等。
阅读全文