1、通过初始化操作建立一个模拟外存空间的虚拟磁盘文件,在该文件中保存目录和文件内容。创建该文件时应创建初始的根目录内容、文件分配表。根目录实为一特殊文件,其开始内容为空,大小为一个块。 2、文件目录项(可以采用FCB格式)应包括类型(目录 or文件)、创建日期、大小、第一个磁盘块块号。 3、显示命令提示符“$”,并根据输入命令完成相应的文件操作: ●MD(创建子目录):创建目录文件,并在父目录文件中增加目录项。 ●RD(删除子目录):搜索所要删除的目录是否为空目录,若是则删除。 ●MK(创建空文件):创建指定大小的文件(如输入命令 “mk test 2000”,表示创建大小为2000字节的test文件),并在父目录中添加文件名称;还应对FAT表进行适当修改。 ●DEL(删除文件):如果所要删除的文件存在,则删除,同时修改父目录内容;还应对FAT表进行适当修改。Python写
时间: 2023-12-14 12:36:32 浏览: 102
以下是一个简单的Python实现,用于模拟一个基本的文件系统,支持创建子目录、删除子目录、创建空文件和删除文件等操作:
```python
import os
import struct
import time
BLOCK_SIZE = 1024 # 磁盘块大小(字节)
DISK_SIZE = 1024 * 1024 # 虚拟磁盘文件大小(字节)
FAT_SIZE = DISK_SIZE // BLOCK_SIZE # FAT表大小(块数)
# FAT表
FAT = [0] * FAT_SIZE
# 根目录项
ROOT_DIR = {
'name': '/',
'type': 'dir',
'created_time': time.time(),
'size': BLOCK_SIZE,
'first_block': 0
}
# 文件目录项(FCB)
FCB_FORMAT = '<8sBIII'
FCB_SIZE = struct.calcsize(FCB_FORMAT)
def init_disk():
'''
初始化虚拟磁盘文件和FAT表
'''
with open('disk.bin', 'wb') as f:
# 创建初始的根目录内容
f.write(struct.pack(FCB_FORMAT, ROOT_DIR['name'].encode('utf-8'), 0, ROOT_DIR['created_time'], ROOT_DIR['size'], ROOT_DIR['first_block']))
f.write(b'\x00' * (BLOCK_SIZE - FCB_SIZE))
# 创建初始的文件分配表
FAT[0] = -1 # 根目录所在块已被占用
for i in range(1, FAT_SIZE):
FAT[i] = 0 # 所有其他块都为空闲状态
# 将FAT表写入虚拟磁盘文件
f.seek(BLOCK_SIZE)
f.write(struct.pack('<%di' % FAT_SIZE, *FAT))
def get_fcb(name, is_dir=False):
'''
根据文件名或目录名获取对应的目录项(FCB)
'''
with open('disk.bin', 'rb') as f:
while True:
data = f.read(FCB_SIZE)
if not data:
return None # 文件不存在
fcb = struct.unpack(FCB_FORMAT, data)
if fcb[0] == name.encode('utf-8'):
if is_dir and fcb[1] == 1:
return None # 找到的是文件,不是目录
if not is_dir and fcb[1] == 0:
return None # 找到的是目录,不是文件
return {
'name': fcb[0].decode('utf-8').strip('\x00'),
'type': 'dir' if fcb[1] == 1 else 'file',
'created_time': fcb[2],
'size': fcb[3],
'first_block': fcb[4]
}
def create_dir(path):
'''
创建目录
'''
if get_fcb(path):
print('Directory already exists')
return
parent_dir_path, dir_name = os.path.split(path)
parent_dir = get_fcb(parent_dir_path, is_dir=True)
if not parent_dir:
print('Parent directory does not exist')
return
# 在父目录中添加目录项
with open('disk.bin', 'r+b') as f:
f.seek(parent_dir['first_block'] * BLOCK_SIZE + parent_dir['size'])
f.write(struct.pack(FCB_FORMAT, dir_name.encode('utf-8'), 1, time.time(), BLOCK_SIZE, -1))
f.write(b'\x00' * (BLOCK_SIZE - FCB_SIZE))
# 更新父目录的大小和FAT表
parent_dir['size'] += BLOCK_SIZE
FAT[parent_dir['first_block']] = 0
for i in range(1, FAT_SIZE):
if FAT[i] == 0:
parent_dir['first_block'] = i
FAT[i] = -1
break
# 更新根目录的FAT表
f.seek(BLOCK_SIZE)
f.write(struct.pack('<%di' % FAT_SIZE, *FAT))
# 在新目录中添加.和..目录项
with open('disk.bin', 'r+b') as f:
f.seek(parent_dir['first_block'] * BLOCK_SIZE)
f.write(struct.pack(FCB_FORMAT, b'.\x00\x00\x00\x00\x00\x00\x00', 1, time.time(), BLOCK_SIZE, parent_dir['first_block']))
f.write(struct.pack(FCB_FORMAT, b'..\x00\x00\x00\x00\x00\x00', 1, time.time(), BLOCK_SIZE, parent_dir['first_block']))
f.write(b'\x00' * (BLOCK_SIZE - 2 * FCB_SIZE))
def remove_dir(path):
'''
删除目录
'''
dir = get_fcb(path, is_dir=True)
if not dir:
print('Directory does not exist')
return
# 检查目录是否为空目录
with open('disk.bin', 'rb') as f:
f.seek(dir['first_block'] * BLOCK_SIZE)
for i in range(2):
data = f.read(FCB_SIZE)
if data:
print('Directory is not empty')
return
# 从父目录中删除目录项
parent_dir_path, dir_name = os.path.split(path)
parent_dir = get_fcb(parent_dir_path, is_dir=True)
with open('disk.bin', 'r+b') as f:
f.seek(parent_dir['first_block'] * BLOCK_SIZE)
while True:
data = f.read(FCB_SIZE)
if not data:
break
fcb = struct.unpack(FCB_FORMAT, data)
if fcb[0] == dir_name.encode('utf-8'):
f.seek(-FCB_SIZE, 1)
f.write(b'\x00' * FCB_SIZE)
parent_dir['size'] -= BLOCK_SIZE
FAT[dir['first_block']] = 0
FAT[parent_dir['first_block']] = -1
break
# 更新根目录的FAT表
f.seek(BLOCK_SIZE)
f.write(struct.pack('<%di' % FAT_SIZE, *FAT))
def create_file(path, size):
'''
创建空文件
'''
if get_fcb(path):
print('File already exists')
return
parent_dir_path, file_name = os.path.split(path)
parent_dir = get_fcb(parent_dir_path, is_dir=True)
if not parent_dir:
print('Parent directory does not exist')
return
# 在父目录中添加文件项
with open('disk.bin', 'r+b') as f:
f.seek(parent_dir['first_block'] * BLOCK_SIZE + parent_dir['size'])
f.write(struct.pack(FCB_FORMAT, file_name.encode('utf-8'), 0, time.time(), size, -1))
f.write(b'\x00' * (BLOCK_SIZE - FCB_SIZE))
# 更新父目录的大小和FAT表
parent_dir['size'] += BLOCK_SIZE
FAT[parent_dir['first_block']] = 0
for i in range(1, FAT_SIZE):
if FAT[i] == 0:
parent_dir['first_block'] = i
FAT[i] = -1
break
# 更新根目录的FAT表
f.seek(BLOCK_SIZE)
f.write(struct.pack('<%di' % FAT_SIZE, *FAT))
def remove_file(path):
'''
删除文件
'''
file = get_fcb(path, is_dir=False)
if not file:
print('File does not exist')
return
# 从父目录中删除文件项
parent_dir_path, file_name = os.path.split(path)
parent_dir = get_fcb(parent_dir_path, is_dir=True)
with open('disk.bin', 'r+b') as f:
f.seek(parent_dir['first_block'] * BLOCK_SIZE)
while True:
data = f.read(FCB_SIZE)
if not data:
break
fcb = struct.unpack(FCB_FORMAT, data)
if fcb[0] == file_name.encode('utf-8'):
f.seek(-FCB_SIZE, 1)
f.write(b'\x00' * FCB_SIZE)
parent_dir['size'] -= BLOCK_SIZE
FAT[file['first_block']] = 0
FAT[parent_dir['first_block']] = -1
break
# 更新根目录的FAT表
f.seek(BLOCK_SIZE)
f.write(struct.pack('<%di' % FAT_SIZE, *FAT))
if __name__ == '__main__':
# 初始化虚拟磁盘文件和FAT表
init_disk()
# 创建子目录
create_dir('/test')
create_dir('/test/subdir')
# 创建空文件
create_file('/test/file1', 1000)
create_file('/test/file2', 2000)
# 删除子目录和文件
remove_dir('/test/subdir')
remove_file('/test/file1')
# 输出根目录内容
with open('disk.bin', 'rb') as f:
f.seek(0)
while True:
data = f.read(FCB_SIZE)
if not data:
break
fcb = struct.unpack(FCB_FORMAT, data)
print(fcb)
```
阅读全文