Exercise 4 实现多级目录
在原有的Nachos文件系统中,文件的目录只有根目录而且根目录中最多能放10个文件。table = new DirectoryEntry[size]
现考虑将存放目录,即table[i]可以代表文件,也可以代表目录。
在目录中增加三个属性,分别为绝对路径,目录地址,和文件类型(分为文件或目录)
其中绝对路径为标识作用
目录地址指的是该文件在哪个目录下,需要先找个此目录再在这个目录中添加表项
class DirectoryEntry {
public:
char *directoryPath;
char *absolutePath;
int fileType;
};
所以在增加table 表项时,需要作如下修改。也很好理解,即将新属性传入表项即可
bool
Directory::AddDirectory(char *absolutePath, char *directoryPath, int newSector) {
if (FindIndex(absolutePath) != -1)return fasle;
for(int i=0;i<tableSize;i++)
if (!table[i].inUse) {
table[i].inUse = TRUE;
table[i].absolutePath = absolutePath;
table[i].directoryPath = directoryPath;
table[i].sector = newSector;
table[i].fileType = DirectoryType;
return TRUE;
}
return FALSE;
}
而创建目录则较为繁琐
bool
CreateDirectory(char *absolutePath,char *directoryPath) {
Directory *directory;
BitMap *freeMap;
FileHeader *hdr;
int sector;
bool success;
int correctSector;
OpenFile *theDirectoryFile;
directory = new Directory(NumDirEntries);
directory->FetchFrom(directoryFile);
//调用getCorrectDirectorySector方法,返回directoryPath所在的文件sector
correctSector = directory->getCorrectDirectorySector(directoryPath);
if (correctSector == -1) {//correctSector为-1,表示没有找到该目录
success = FASLE;
}
else{
//如果不是根目录,则要获得该目录的对应扇区sector的存储的目录
if (correctSector != 1) {
delete directory;
theDirectoryFile = new OpenFile(correctSector);
directory = new Directory(NumDirEntries);
directory->FetchFrom(theDirectoryFile);
}
//此目录下已经有同名文件
if (directory->Find(absolutePath) != -1) {
success = FALSE;
}
else {
//开始创建文件,分为创建头文件和分配文件内容
freeMaP = new BitMap(NumSectors);
freeMap->FetchFrom(FreeMapFile);
sector = freeMap->Find();
if (sector != -1)success = FALSE;//给头文件分配扇区,但空间分配耗尽
else if (!directory->AddDirectory(absolutePath, directoryPath, sector))success = FALSE;//扇区目录分配完毕
else {
hdr = new FileHeader;
if (!hdr->Allocate(freeMap, DirectoryFileSize))success = FALSE;//给文件具体内容分配扇区,但耗尽空间
else {
success = TRUE;
hdr->WriteBack(sector);
directory->WriteBack(directoryFile);
OpenFile *newDirectoryFile = new OpenFile(sector);
Directory *newDirectory = new Directory(NumDirEntries);
newDirectory->WriteBack(newDirectoryFile);
delete newDirectory;
delete newDirectoryFile;
}
delete hdr;
}
}
}
}
int
Directory : getCorrectDirectorySector(char *directoryPath) {
int directorySector = -1;//如果没有找到文件,则返回-1
char *root = “root/”;
int test = strcmp(root, directoryPath);
if (test == 0)return 1;//directoryPath为根目录,返回根目录
else {
int index =direcotry->Find(directoryPath);
if (index != -1)return index;//在根目录找到对应的子目录,返回子目录所在的扇区
else {
for (int i = 0; i < tableSize; i++) {
//对应的目录再某个子目录下,需要进入子目录后再递归调用该方法
if (table[i].inUse && (table[i].fileType == DirectoryType)) {//找寻此目录下正在使用的文件。第一次是根目录
int directoryIndex = table[i].sector
OpenFile *tempOpenFile = new OpenFile(directoryIndex);
Direcotry *directory = new Directory(200);
directory->FetchFrom(tempOpenFile);
directorySector = directory->getCorrectDirectorySector(table[i].absolutePath);
delete tempOpenFile
}
}
}
}
return directorySector;
}