2021SC@SDUSC
项目环境:
- 树莓派4b
- Ubuntu Desktop 21.04
读取文件:
下面是读取文件函数 readFile 的实现;在该函数中,文件名 name 作为形参传入。
首先读取 inode :
PInode pInode = new Inode();
getInode(pInode, id);
然后,依次遍历 10 个直接索引,读取数据块。这其中要分几种情况进行讨论。首先,如果文件的长度超过了 blocksize ,那么长度就要更新为原有的长度减去 getData 获取的 blocksize 的长度,若文件长度未超过 blocksize ,则 len 的长度更新为 len 减去 blocks ize 的长度,并将缓冲区删除。之后的遍历一个一级索引也是类似的操作。
for(i = 0; i < 10; i++)
{
blockId = pInode->addr[i];
if(blockId > 0)
{
if(len > blockSize)
{
len -= getData(blockId, buff, blockSize, 0);
printf("%s", buff);
}
else
{
len -= getData(blockId, buff, len, 0);
printf("%s\n", buff);
delete buff;
return 0;
}
}
else
{
printf("\n");
delete buff;
return 0;
}
}
下面考虑遍历二级索引:
for(i = 0; i < totalItem; i++)
{
blockId = getItem(addrBlockId, i);
if(blockId > 0)
{
if(len > blockSize)
{
len -= getData(blockId, buff, blockSize, 0);
printf("%s", buff);
}
else
{
len -= getData(blockId, buff, len, 0);
printf("%s\n", buff);
delete buff;
return 0;
}
}
else
{
printf("\n");
delete buff;
return 0;
}
}
与遍历一级索引是类似的。
文件写入:
下面是文件写入 Write 的实现。
首先,我们依然是读取节点 PInode pInode = new Inode(); getInode(pInode, id); 然后,我们定义一个缓冲区 char* buff = new char[blockSize+1]; 对于 10 个直接索引对应的数据块,我们可以进行直接读取。
for(i = 0; i < 10; i++)
{
blockId = pInode->addr[i];
if(blockId > 0)
{
num = waitForInput(buff, blockSize);
writeData(blockId, buff, num, 0);
len += num;
if(num < blockSize)
{
pInode->length = len;
time(&(pInode->time));
updateInode(*pInode);
delete buff;
return 0;
}
else
{
printf("You have input %ld Byte dat, continue?[Y/N]", len);
ch = getchar();
if(ch != 'Y' && ch != 'y')
{
pInode->length = len;
time(&(pInode->time));
updateInode(*pInode);
delete buff;
return 0;
}
}
}
需要注意,同写入文件一样,需要对需要写入的数据大小与 blocksize 的大小进行一下比较,当 num 小于 blocksize 的时候,可以直接进行写入,并更新索引节点 pnode ,然后删除缓冲区。
写入数据之后,将空闲数据块的数目 blockFree 自减,并对其进行更新,然后更新数据块比特图,然后更新索引节点 p