为linux系统设计一个简单的二级文件系统代码。要求做到以下几点: (1)可以实现下列几条命令(至少4条); dir 列文件目录 create 创建文件 delete 删除文件 open 打开文件 close 关闭文件 read 读文件 write 写文件 (2)列目录时要列出文件名、物理地址、保护码和文件长度; (3)源文件可以进行读写保护。
时间: 2024-01-30 12:01:54 浏览: 129
首先,需要了解什么是二级文件系统。二级文件系统是指在主文件系统上再建立一个文件系统。文件系统的组织方式是树形结构,文件和目录都是树形结构中的节点,文件可以包含其他文件或目录。每个目录下都可以有多个文件或子目录,每个文件或子目录都有一个唯一的名字。文件系统中的每个文件都有一个唯一的标识符,称为inode号。
下面是一个简单的二级文件系统代码的实现:
```c
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<unistd.h>
#include<fcntl.h>
#include<sys/stat.h>
#include<sys/types.h>
#define MAX_FILE_NAME 100
#define MAX_FILE_SIZE 1024
//文件控制块FCB
struct FCB{
char fileName[MAX_FILE_NAME];
int inode;
char protectCode[3];
int fileSize;
};
//磁盘块
struct diskBlock{
char data[MAX_FILE_SIZE];
};
//i节点
struct inode{
struct diskBlock* directBlock[10]; //直接块
struct diskBlock* indirectBlock; //间接块
int fileSize; //文件大小
};
//文件系统管理
struct fileSystem{
struct FCB* fcbTable[MAX_FILE_SIZE];
struct inode* inodeTable[MAX_FILE_SIZE];
struct diskBlock* diskBlockTable[MAX_FILE_SIZE];
int fcbTableSize;
int inodeTableSize;
int diskBlockTableSize;
};
//初始化文件系统
void initFileSystem(struct fileSystem* fs){
fs->fcbTableSize = 0;
fs->inodeTableSize = 0;
fs->diskBlockTableSize = 0;
}
//创建文件
int createFile(struct fileSystem* fs, char* fileName, char* protectCode){
//检查文件名是否冲突
int i;
for(i=0; i<fs->fcbTableSize; i++){
if(strcmp(fileName, fs->fcbTable[i]->fileName) == 0){
printf("File already exists!\n");
return -1;
}
}
//创建FCB
struct FCB* fcb = (struct FCB*)malloc(sizeof(struct FCB));
strcpy(fcb->fileName, fileName);
strcpy(fcb->protectCode, protectCode);
fcb->fileSize = 0;
fcb->inode = fs->inodeTableSize;
fs->fcbTable[fs->fcbTableSize++] = fcb;
//创建inode
struct inode* inode = (struct inode*)malloc(sizeof(struct inode));
inode->fileSize = 0;
int i;
for(i=0; i<10; i++){
inode->directBlock[i] = NULL;
}
inode->indirectBlock = NULL;
fs->inodeTable[fs->inodeTableSize++] = inode;
return 0;
}
//删除文件
int deleteFile(struct fileSystem* fs, char* fileName){
//查找并删除FCB和inode
int i;
for(i=0; i<fs->fcbTableSize; i++){
if(strcmp(fileName, fs->fcbTable[i]->fileName) == 0){
free(fs->fcbTable[i]);
fs->fcbTable[i] = NULL;
free(fs->inodeTable[i]);
fs->inodeTable[i] = NULL;
printf("Delete file %s successfully!\n", fileName);
return 0;
}
}
printf("File not found!\n");
return -1;
}
//打开文件
int openFile(struct fileSystem* fs, char* fileName, char* mode){
int i;
for(i=0; i<fs->fcbTableSize; i++){
if(strcmp(fileName, fs->fcbTable[i]->fileName) == 0){
//检查读写权限
if(strcmp(mode, "r") == 0 && fs->fcbTable[i]->protectCode[0] != 'r'){
printf("No read permission!\n");
return -1;
}
if(strcmp(mode, "w") == 0 && fs->fcbTable[i]->protectCode[1] != 'w'){
printf("No write permission!\n");
return -1;
}
if(strcmp(mode, "a") == 0 && fs->fcbTable[i]->protectCode[1] != 'w'){
printf("No write permission!\n");
return -1;
}
//返回inode号
printf("Open file %s successfully!\n", fileName);
return fs->fcbTable[i]->inode;
}
}
printf("File not found!\n");
return -1;
}
//关闭文件
int closeFile(struct fileSystem* fs, int inode){
printf("Close file %d successfully!\n", inode);
return 0;
}
//读文件
int readFile(struct fileSystem* fs, int inode, char* buffer, int size, int offset){
if(inode<0 || inode>=fs->inodeTableSize || fs->inodeTable[inode]==NULL){
printf("Invalid inode!\n");
return -1;
}
int readSize = size;
if(offset+size > fs->inodeTable[inode]->fileSize){
readSize = fs->inodeTable[inode]->fileSize - offset;
}
int i;
for(i=0; i<10 && readSize>0; i++){
if(fs->inodeTable[inode]->directBlock[i] != NULL){
int blockSize = readSize<MAX_FILE_SIZE ? readSize : MAX_FILE_SIZE;
memcpy(buffer, fs->inodeTable[inode]->directBlock[i]->data+offset%MAX_FILE_SIZE, blockSize);
readSize -= blockSize;
buffer += blockSize;
offset += blockSize;
}
}
if(readSize > 0 && fs->inodeTable[inode]->indirectBlock != NULL){
int blockNum = (readSize-1)/MAX_FILE_SIZE+1;
int* blockIndex = (int*)fs->inodeTable[inode]->indirectBlock->data;
for(i=0; i<blockNum && readSize>0; i++){
if(fs->diskBlockTable[blockIndex[i]] != NULL){
int blockSize = readSize<MAX_FILE_SIZE ? readSize : MAX_FILE_SIZE;
memcpy(buffer, fs->diskBlockTable[blockIndex[i]]->data+offset%MAX_FILE_SIZE, blockSize);
readSize -= blockSize;
buffer += blockSize;
offset += blockSize;
}
}
}
printf("Read file %d successfully!\n", inode);
return size-readSize;
}
//写文件
int writeFile(struct fileSystem* fs, int inode, char* buffer, int size, int offset){
if(inode<0 || inode>=fs->inodeTableSize || fs->inodeTable[inode]==NULL){
printf("Invalid inode!\n");
return -1;
}
int writeSize = size;
if(offset+size > MAX_FILE_SIZE*10+MAX_FILE_SIZE*MAX_FILE_SIZE){
printf("File is too large!\n");
return -1;
}
int i;
for(i=0; i<10 && writeSize>0; i++){
if(fs->inodeTable[inode]->directBlock[i] == NULL){
fs->inodeTable[inode]->directBlock[i] = (struct diskBlock*)malloc(sizeof(struct diskBlock));
fs->diskBlockTable[fs->diskBlockTableSize++] = fs->inodeTable[inode]->directBlock[i];
}
int blockSize = writeSize<MAX_FILE_SIZE ? writeSize : MAX_FILE_SIZE;
memcpy(fs->inodeTable[inode]->directBlock[i]->data+offset%MAX_FILE_SIZE, buffer, blockSize);
writeSize -= blockSize;
buffer += blockSize;
offset += blockSize;
}
if(writeSize > 0){
if(fs->inodeTable[inode]->indirectBlock == NULL){
fs->inodeTable[inode]->indirectBlock = (struct diskBlock*)malloc(sizeof(struct diskBlock));
fs->diskBlockTable[fs->diskBlockTableSize++] = fs->inodeTable[inode]->indirectBlock;
}
int blockNum = (writeSize-1)/MAX_FILE_SIZE+1;
int* blockIndex = (int*)fs->inodeTable[inode]->indirectBlock->data;
for(i=0; i<blockNum && writeSize>0; i++){
if(blockIndex[i] == 0){
fs->diskBlockTable[fs->diskBlockTableSize] = (struct diskBlock*)malloc(sizeof(struct diskBlock));
blockIndex[i] = fs->diskBlockTableSize++;
}
int blockSize = writeSize<MAX_FILE_SIZE ? writeSize : MAX_FILE_SIZE;
memcpy(fs->diskBlockTable[blockIndex[i]]->data+offset%MAX_FILE_SIZE, buffer, blockSize);
writeSize -= blockSize;
buffer += blockSize;
offset += blockSize;
}
}
fs->inodeTable[inode]->fileSize = offset;
printf("Write file %d successfully!\n", inode);
return size-writeSize;
}
//列文件目录
void listDir(struct fileSystem* fs){
printf("%-20s%-20s%-20s%-20s\n", "File Name", "Inode", "Protect Code", "File Size");
int i;
for(i=0; i<fs->fcbTableSize; i++){
if(fs->fcbTable[i] != NULL){
printf("%-20s%-20d%-20s%-20d\n", fs->fcbTable[i]->fileName, fs->fcbTable[i]->inode, fs->fcbTable[i]->protectCode, fs->fcbTable[i]->fileSize);
}
}
}
int main(){
struct fileSystem fs;
initFileSystem(&fs);
createFile(&fs, "file1.txt", "rw");
createFile(&fs, "file2.txt", "r");
listDir(&fs);
char buffer[MAX_FILE_SIZE];
int size = 20;
int offset = 0;
int inode = openFile(&fs, "file1.txt", "r");
readFile(&fs, inode, buffer, size, offset);
printf("%s\n", buffer);
closeFile(&fs, inode);
char str[] = "Hello world!";
size = strlen(str);
offset = 0;
inode = openFile(&fs, "file1.txt", "w");
writeFile(&fs, inode, str, size, offset);
closeFile(&fs, inode);
inode = openFile(&fs, "file1.txt", "r");
readFile(&fs, inode, buffer, size, offset);
printf("%s\n", buffer);
closeFile(&fs, inode);
deleteFile(&fs, "file1.txt");
listDir(&fs);
return 0;
}
```
以上代码实现了文件的创建、删除、打开、关闭、读取和写入功能,并可以列出文件目录。其中,FCB保存文件名、inode号、保护码和文件大小信息,inode保存文件内容和大小信息,diskBlock保存磁盘块数据。在读取和写入函数中,采用了直接块和间接块的方式来存储文件数据,并且可以处理超过直接块容量的文件。在打开文件时,需要检查读写权限。
阅读全文