操作系统实验四——文件系统的简单命令的设计与实现

本文档详细介绍了如何用C++实现文件系统中的`cp`命令,该命令用于复制文件。主要步骤包括打开源文件、读取内容至缓冲区、创建并打开目标文件、将缓冲区内容写入目标文件以及关闭目标文件。通过read函数完成文件读取,最终实现了文件的复制功能。
摘要由CSDN通过智能技术生成

要求:

实现文件系统的简单命令,此篇文件实现命令:cp。cp 是copy的缩写,使用格式为cp srcname dstname;

说明:此文件系统使用c++实现,我们要实现cp命令,大概分这几步:

1、打开源文件 

2、读取源文件内容到缓冲区

3、创建目标文件 

4、打开目标文件

5、将缓冲区内容写入目标文件

6、关闭目标文件


因为,cp命令的代码为:

int FILESYS::cp(char *src, char *dst)
{
    bool open_flag = false;
    int i;
    //确保没有打开过该文件 = 相同名字 + 相同目录
    for(i=0; i<OPEN_MAX; i++)
    {
        if(openedFiles->f[i].type ==1 && strcmp(openedFiles->f [i].fname,src)==0
                &&openedFiles->f[i].fatherBlockNum == current)
        {
            open_flag = true;
            break;
        }
    }
    if(!open_flag)  open(src);

    char buf[BUFSIZ] = {'#'};
    size_t size = read(src,buf);
    create(dst);
    open(dst);
    write(dst,buf,size);
    close(dst);
    if(!open_flag) close(src);
    printf("---------------------------------------------------copy done!\n\n");
    return 1;
}

在此处,我们重载了 write 和 read函数

read函数:

/*---------选择一个打开的文件读取信息到缓冲区----------*/
int  FILESYS::read(char *file, char *buf, size_t size)
{
    int i,fileStartNum;
    char *startPoint,*endPoint;

    //在打开文件列表中查找 file(还需要考虑同名不同目录文件的情况!!!)
    for(i=0; i<OPEN_MAX; i++)
    {
        if(strcmp(openedFiles->f [i].fname,file)==0 )
        {
            if(openedFiles->f[i].fatherBlockNum ==current)
            {
                break;
            }
            else
            {
                printf("该文件处于打开列表中,本系统只能阅读当前目录下文件!\n");
                return 0;
            }
        }
    }

    if(i==OPEN_MAX)
    {
        printf("该文件尚未打开,请先打开后读取信息!\n");
        return 0;
    }
    int active=i;

    //计算文件物理地址
    fileStartNum = openedFiles->f[active].currentBlockNum - 3 ;
    startPoint = data[fileStartNum];
    endPoint = data[fileStartNum + 1];
    //end_dir=(struct dirFile *)[BlockSize-1];

    //q=(char *)end_dir;

    //printf("该文件的内容为:  ");
    i = 0;
    if(size<=0)
    {
        while((*startPoint)!='#'&& (startPoint < endPoint))
        {
            buf[i] = *startPoint++;
            i++;
        }
    }
    else
    {
        while((*startPoint)!='#'&& (startPoint < endPoint) && (i < size))
        {
            buf[i] = *startPoint++;
            i++;
        }
    }
    buf[i] = '#';

    return i;
}

write函数:

int FILESYS::write(char *name, char *buf, size_t size)
{
    int i;
    char *startPoint,*endPoint;
    //在打开文件列表中查找 file(还需要考虑同名不同目录文件的情况!!!)
    for(i=0; i<OPEN_MAX; i++)
    {
        if(strcmp(openedFiles->f [i].fname,name)==0 )
        {
            if(openedFiles->f[i].fatherBlockNum ==current)
            {
                break;
            }
            else
            {
                printf("该文件处于打开列表中,本系统只能改写当前目录下文件!\n");
                return 0;
            }
        }
    }

    if(i==OPEN_MAX)
    {
        printf("该文件尚未打开,请先打开后写入信息!!\n");
        return 0;
    }

    int active=i;
    int fileStartNum = openedFiles->f[active].currentBlockNum - 3 ;
    startPoint = data[fileStartNum];
    endPoint = data[fileStartNum + 1];

    //printf("请输入文本以#号结束:\t");

    char input;
    i = 0;
    do
    {
        if(startPoint < endPoint-1)
        {
            *startPoint++ = buf[i];
        }
        else
        {
            printf("达到单体文件最大容量!");
            *startPoint++ = '#';
            break;
        }
    }
    while(++i < size);
    *startPoint = '#';

    return i;
}

最后,我们要处理键盘输入的命令,需要增加以下几行代码:

else if(cmd=="cp")
        {
            char src[BUFSIZ];
            char dst[BUFSIZ];
            cin>>src;
            cin>>dst;
            fileSystem.cp(src,dst);
        }

好了,上全部代码

// filesystem.cpp : Defines the entry point for the console application.
//

//#include "stdafx.h"
#include "stdio.h"
#include "stdlib.h"
#include "string.h"
#include "iostream"

using namespace std;

typedef struct
{
    char fname[16]; //file name
    int type;    //1 for usual file, 2 for dir file, 0 for null
    int size;    //file size
    int fatherBlockNum;    //father dir block num
    int currentBlockNum;    //current block num
} FCB;

/*const setting*/
const char* FilePath = "C:\\myfiles";
const int BlockSize = 512;       //block size
const int OPEN_MAX = 5;          //MAX FILE OPENED
const int BlockCount = BlockSize/sizeof(int);   //BLOCK ITEMS IN A BLOCK
const int DiskSize = BlockSize*BlockCount;    //DISK CONTENT
const int BlockFcbCount = BlockSize/sizeof(FCB);//FILE ITEMS IN A DIR
const int PATHLEN=256;
int OpenFileCount = 0;


class OPENLIST
{
public:
    int files;
    FCB *f;

public:
    OPENLIST();
    ~OPENLIST();
};

OPENLIST::OPENLIST()
{
    f=new FCB[OPEN_MAX];
}

OPENLIST::~OPENLIST()
{
    //delete [OPEN_MAX]f;
    delete f;
}

class dirFile
{
public:
    FCB fcb[BlockFcbCount];
    dirFile();
    void initDir(int _FatherBlockNum,int _CurrentBlockNum,const char *name);//父块号,当前块号,目录名
    void initFile(FCB &filefcb);
};

dirFile::dirFile()
{
    //printf("");
    return;
}

void dirFile::initDir(int _FatherBlockNum,int _CurrentBlockNum,const char *name)//父块号,当前块号,目录名
{
    strcpy(fcb[0].fname,name); //本身的FCB
    fcb[0].fatherBlockNum=_FatherBlockNum;
    fcb[0].currentBlockNum=_CurrentBlockNum;
    fcb[0].type=2;     //标记目录文件

    for(int i=1; i<BlockFcbCount; i++)
    {
        fcb[i].fatherBlockNum=_CurrentBlockNum; //标记为子项
        fcb
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值