完整源码见本人博客下载资源
单层索引的结构
dataSector数组有NumDirect项(按一个i-node占用空间不超过一个扇区的原则,计算可得NumDirect为30),每一项都是直接的单层索引,指向文件所占扇区。由此可得,文件最大大小是,30*128 bytes=3840bytes
private:
int numBytes; // Number of bytes in the file
int numSectors; // Number of data sectors in the file
int dataSectors[NumDirect]; // Disk sector numbers for each data
// block in the file
功能
public:
bool Allocate(BitMap *bitMap, int fileSize);// Initialize a file header,
// including allocating space
// on disk for the file data
void Deallocate(BitMap *bitMap); // De-allocate this file's
// data blocks
void FetchFrom(int sectorNumber); // Initialize file header from disk
void WriteBack(int sectorNumber); // Write modifications to file header
// back to disk
int ByteToSector(int offset); // Convert a byte offset into the file
// to the disk sector containing
// the byte
int FileLength(); // Return the length of the file
// in bytes
void Print(); // Print the contents of the file.
//***********************************newSize(bytes)
bool ExtendFile(OpenFile *bitmapfile,int newSize);
bool CutFile(OpenFile *bitmapfile,int newSize);
如图所示,我构建具有二级索引的i-node,思想就是这样,原先的前NumDirect-1项还是直接索引,最后一项,可以指向另一个块,这个块存放新的直接索引条目,因此产生二级索引,扩大了文件的最大size=(29+32)*128 bytes
二级的索引块是动态产生的,当文件大小不需要它时,最后一项设置为-1;当文件大小一级索引无法支持,再分配一个新的块存索引,将其地址存入最后一项,形成图上结构。
FileHeader类的私有成员和接口定义无需更改;但是除了FetchFrom,WriteBack,FileLength外的函数实现都要更改,以支持二级索引。三、实现步骤
bool
FileHeader::Allocate(BitMap *freeMap, int fileSize)
{
numBytes = fileSize;
numSectors = divRoundUp(fileSize, SectorSize);
if (numSectors >MaxNumSector || freeMap->NumClear() < numSectors)
return FALSE; // 超出文件最大size||not enough space
if (numSectorsFind();
dataSectors[NumDirect-1] = -1; //无二级索引,最后一项是-1
}else{ //使用二级索引
printf("!!!Allocate使用二级索引!!!");
for (int i = 0; i < NumDirect; i++)
dataSectors[i] = freeMap->Find(); //最后一项是二级块的地址
int dataSectors2[NumIndirect];
for (int i=0; i < numSectors-NumDirect+1; i++)
dataSectors2[i] = freeMap->Find();
//将二级索引保存
synchDisk->WriteSector(dataSectors[NumDirect-1], (char *)dataSectors2);
}
return TRUE;
}
void
FileHeader::Deallocate(BitMap *freeMap)
{
if (numSectorsTest((int) dataSectors[i])); // ought to be marked!
freeMap->Clear((int) dataSectors[i]);
}
else{
printf("!!!Deallocate使用二级索引!!!");
int dataSectors2[NumIndirect];
synchDisk->ReadSector(dataSectors[NumDirect-1], (char *)dataSectors2);
for (int i = 0; i < NumDirect; i++){
ASSERT(freeMap->Test((int) dataSectors[i])); // ought to be marked!
freeMap->Clear((int) dataSectors[i]);
}
for (int i=0; i < numSectors-NumDirect+1; i++){
ASSERT(freeMap->Test((int) dataSectors2[i])); // ought to be marked!
freeMap->Clear((int) dataSectors2[i]);
}
}
}
int
FileHeader::ByteToSector(int offset)
{
int sectorTh= offset / SectorSize;
if (sectorTh < NumDirect-1)
return(dataSectors[sectorTh]);
else{
int dataSectors2[NumIndirect];
synchDisk->ReadSector(dataSectors[NumDirect-1], (char *)dataSectors2);
printf("########Kuai hao: %d\n",dataSectors2[sectorTh-NumDirect+1]);
return(dataSectors2[sectorTh-NumDirect+1]);
}
}
void
FileHeader::Print()
{
int i, j, k;
char *data = new char[SectorSize];
if(numSectorsReadSector(dataSectors[i], data);
for (j = 0; (j < SectorSize) && (k < numBytes); j++, k++) {
if ('\040' <= data[j] && data[j] <= '\176') // isprint(data[j])
printf("%c", data[j]);
else
printf("\\%x", (unsigned char)data[j]);
}
printf("\n");
}
}else{
printf("!!!Print使用二级索引!!!");
int dataSectors2 [NumIndirect];
synchDisk->ReadSector(dataSectors[NumDirect-1], (char *)dataSectors2);
printf("FileHeader contents. File size: %d. File blocks:\n", numBytes);
for (i = 0; i < NumDirect-1; i++)
printf("%d ", dataSectors[i]);
printf("\n二级索引块号%d ", dataSectors[NumDirect-1]);
for (i = 0; i < numSectors-NumDirect+1; i++)
printf("%d ", dataSectors2[i]);
for (i = k = 0; i < NumDirect-1; i++) {
synchDisk->ReadSector(dataSectors[i], data);
for (j = 0; (j < SectorSize) && (k < numBytes); j++, k++) {
if ('\040' <= data[j] && data[j] <= '\176') // isprint(data[j])
printf("%c", data[j]);
else
printf("\\%x", (unsigned char)data[j]);
}
printf("\n");
}
for (i = 0; i < numSectors-NumDirect+1; i++) {
synchDisk->ReadSector(dataSectors2[i], data);
for (j = 0; (j < SectorSize) && (k < numBytes); j++, k++) {
if ('\040' <= data[j] && data[j] <= '\176') // isprint(data[j])
printf("%c", data[j]);
else
printf("\\%x", (unsigned char)data[j]);
}
printf("\n");
}
}
delete [] data;
}
bool
FileHeader::ExtendFile(OpenFile *bitmapfile,int newSize)
{
int newNumSectors = divRoundUp(newSize, SectorSize);//上取整
if(newNumSectors == numSectors){
numBytes = newSize;
printf("扩展文件成功\n");
return true; //扇区数量不变
}
int diffSector = newNumSectors - numSectors;
// OpenFile *bitmapfile = new OpenFile(0);
BitMap *freeMap = new BitMap(NumSectors);
freeMap->FetchFrom(bitmapfile);
//printf("debug in fhdr extend where new Sector=%d \n",newNumSectors);
if(newNumSectors>MaxNumSector||freeMap->NumClear()< diffSector){
printf("扩展文件失败\n");
return false; //磁盘空间不足
}
//allocate the new sectors and store them into file header
int i;
if (newNumSectorsFind();
//printf("debug in fhdr extend #########NEW KUAI HAO=%d \n",dataSectors[i]);
}
}else{
printf("!!!ExtendFile使用二级索引!!!");
if(numSectorsFind();
}
int dataSectors2 [NumIndirect];
for (i=0; i < newNumSectors-NumDirect+1; i++)
dataSectors2 [i] = freeMap->Find();
//将二级索引保存
synchDisk->WriteSector(dataSectors[NumDirect-1], (char *)dataSectors2);
}else{//原来有二级索引
int dataSectors2 [NumIndirect];
synchDisk->ReadSector(dataSectors[NumDirect-1], (char *)dataSectors2);
for (i=numSectors-NumDirect+1; i < newNumSectors-NumDirect+1; i++)
dataSectors2[i] = freeMap->Find();
//将二级索引保存
synchDisk->WriteSector(dataSectors[NumDirect-1], (char *)dataSectors2);
}
}
numBytes = newSize;
numSectors = newNumSectors;
freeMap->WriteBack(bitmapfile);
printf("扩展文件成功\n");
return true;
}
bool
FileHeader::CutFile(OpenFile *bitmapfile,int newSize)
{
int newNumSectors = divRoundUp(newSize, SectorSize);//上取整
if(newNumSectors == numSectors){
numBytes = newSize;
printf("cut文件成功\n");
return true; //扇区数量不变
}
//OpenFile *bitmapfile = new OpenFile(0);
BitMap *freeMap = new BitMap(NumSectors);
freeMap->FetchFrom(bitmapfile);
//cut off
int i;
if(numSectorsClear(dataSectors[i]);
}
else{
printf("!!!CutFile使用二级索引!!!");
int dataSectors2[NumIndirect];
synchDisk->ReadSector(dataSectors[NumDirect-1], (char *)dataSectors2);
if(newNumSectorsClear(dataSectors2[i]);
for (i = newNumSectors; iClear(dataSectors[i]);
dataSectors[NumDirect-1]= -1; //二级索引去掉
}else{
for(int i=newNumSectors-NumDirect+1; i < numSectors-NumDirect+1; i++)
freeMap->Clear(dataSectors[i]);
//将二级索引保存
synchDisk->WriteSector(dataSectors[NumDirect-1], (char *)dataSectors2);
}
}
numBytes = newSize;
numSectors = newNumSectors;
freeMap->WriteBack(bitmapfile);
printf("cut文件成功\n");
return true;
}