操作系统文件系统模拟

操作系统简单文件系统模拟(Java和C++):

结果展示:

没有持久化存储到本地系统盘,演示结果:使用Java语言实现,附带C++版本

在这里插入图片描述

逻辑解释

主要的两个类:文件夹和文件

class FOLDER{//目录结构
    String name=new String();//目录名
    FOLDER nextFolder;//同级下一目录
    FOLDER frontFolder;//同级上一目录
    FOLDER parentFolder;//父目录
    FOLDER firstChildFolder;//子目录
    FOLDER lastChildFolder;//最后一个子文件夹
    FILE firstChildFile;//子文件
    FILE lastChildFile;

    public FOLDER(String name, FOLDER nextFolder, FOLDER frontFolder, FOLDER parentFolder, FOLDER firstChildFolder, FOLDER lastChildFolder, FILE firstChildFile, FILE lastChildFile)
    {
        this.name = name;
        this.nextFolder = nextFolder;
        this.frontFolder = frontFolder;
        this.parentFolder = parentFolder;
        this.firstChildFolder = firstChildFolder;
        this.lastChildFolder = lastChildFolder;
        this.firstChildFile = firstChildFile;
        this.lastChildFile = lastChildFile;
    }
    public FOLDER() {}
}
class FILE{
    String name=new String();//文件名
    String content=new String();//文件内容
    FILE frontFile;//同级目录上一文件
    FILE nextFile;//同级目录下一文件
    FOLDER parentFolder;//父目录
    public FILE(String name, String content, FILE frontFile, FILE nextFile, FOLDER parentFolder) {
        this.name = name;
        this.content = content;
        this.frontFile = frontFile;
        this.nextFile = nextFile;
        this.parentFolder = parentFolder;
    }
    public FILE() {}
}

解释:有一个总的root文件夹,每一个文件夹类,采用类似链表的连接方式,记录当前目录下的第一个文件夹和最后一个文件夹,可以遍历查找,而文件也是同样的方式。

代码实现

实现的Java代码:

import java.util.Objects;
import java.util.Scanner;

public class FileSystem {
    FOLDER root,nowpath;

    public static void main(String[] args) {
        FileSystem init = new FileSystem();
        init.createRoot();
        init.menu();
    }
    // 切换目录
    void open_dir(String name) {
        // 返回上一层目录
        if(Objects.equals(name, "../")){
            if(nowpath!=root)
                nowpath = nowpath.parentFolder;
            return;
        }
        FOLDER a = nowpath.firstChildFolder;
        while(a!=null && !Objects.equals(a.name, name))
            a = a.nextFolder;
        if(a==null || !Objects.equals(a.name, name)){
            System.out.println("没有找到"+name);
            return;
        }
        nowpath = a;
    }
    // 展示目录
    void showInfo() {
        FOLDER x = nowpath.firstChildFolder;
        while(x!=null){
            System.out.println(x.name);
            x = x.nextFolder;
        }
        FILE y = nowpath.firstChildFile;
        while (y!=null){
            System.out.println(y.name);
            y = y.nextFile;
        }
    }

    // 修改文件
    void modify(String name) {
        FILE a = nowpath.firstChildFile;
        FILE b = nowpath.lastChildFile;
        while (a!=null && !Objects.equals(a.name, name))
            a = a.nextFile;
        if(a==null || !Objects.equals(a.name, name)){
            System.out.println("没有找到"+name);
            return;
        }
        System.out.print("选择续写: 1\n覆盖写入: 2\n");
        Scanner in = new Scanner(System.in);
        int op = in.nextInt();
        if(op==2) a.content = "";
        System.out.println("输入内容");
        in.nextLine(); //吞掉换行符
        String s = in.nextLine();
        System.out.println(s+"-------检测输入");
        if(a.content!=null) a.content = a.content+s;
        else a.content = s;
    }
    // 查看文件内容
    void show_context(String name) {
        FILE a = nowpath.firstChildFile;
        while(a!=null && !Objects.equals(a.name, name))
            a = a.nextFile;
        if(a==null || !Objects.equals(a.name, name)){
            System.out.println("没有找到"+name+"文件");
            return;
        }
        else System.out.println(a.content);
    }
    // 删除文件
    void rm(String name) {
        boolean flag = false;
        FILE a = nowpath.firstChildFile;
        FILE b = nowpath.lastChildFile;
        if(a==null){
            if (flag) System.out.println("成功删除");
            else System.out.println("不存在"+name+"文件");
            return;
        }
        // 第一个文件就是要找的文件
        if(a!=null && Objects.equals(a.name, name)){
            flag = true;
            boolean fl = a == b ? true : false;
            FILE nxt = a.nextFile;//是否还有其他文件
            nowpath.firstChildFile = nxt;
            if (nxt != null)
                nxt.frontFile = null;
            if (fl)
                nowpath.lastChildFile = null;
        }
        else if(b!=null && Objects.equals(b.name, name)){
            flag = true;
            FILE pre = b.frontFile;
            nowpath.lastChildFile = pre;
            if(pre!=null)
                pre.nextFile = null;
        }
        else { // 不是第一个和最后一个文件,从头遍历查找此文件
            if(a.nextFile!=null) a = a.nextFile;
            while (a!=null && a!=b && !Objects.equals(a.name, name))
                a = a.nextFile;
            if (a != null && Objects.equals(a.name, name))
            {
                flag = true;
                FILE pre = a.frontFile;
                FILE nxt = a.nextFile;
                if (pre != null)
                    pre.nextFile = nxt;
                if (nxt != null)
                    nxt.frontFile = pre;
            }
        }
        if (flag) System.out.println("成功删除");
        else System.out.println("不存在"+name+"文件");
    }
    // 创建文件
    void touch_file(String name) {
        FILE x = nowpath.firstChildFile;
        FILE y = nowpath.lastChildFile;
        boolean flag = true;
        while (x!=y){
            if(Objects.equals(x.name, name))
                flag = false;
            x = x.nextFile;
        }
        if(y!=null && Objects.equals(y.name, name))
            flag = false;
        if(!flag){
            System.out.println("当前文件名已存在");
            return;
        }
        FILE newFile = new FILE(name,null,null,null,nowpath);
        if (nowpath.firstChildFile == null){
            nowpath.firstChildFile = newFile;
            nowpath.lastChildFile = newFile;
        }
        else
        {
            FILE b = nowpath.lastChildFile;
            b.nextFile = newFile;
            newFile.frontFile = b;
            nowpath.lastChildFile = newFile;
        }
    }

    void del(FOLDER a){
        if (a == null) return;
        FILE x = a.firstChildFile;
        FILE y = a.lastChildFile;
        while (x != y)
        {
            FILE t = x.nextFile;
            x = t;
        }

        FOLDER xF = a.firstChildFolder;
        FOLDER yF = a.lastChildFolder;
        while (xF != yF)
        {
            FOLDER t = xF.nextFolder;
            del(xF);
            xF = t;
        }
        if (yF != null)
        {
            del(yF);
        }
    }
    // 删除文件夹
    void remove_directory(String name) {
        boolean flag = false;
        FOLDER a = nowpath.firstChildFolder;
        FOLDER b = nowpath.lastChildFolder;
        if(a==null){
            if(flag) System.out.println("成功删除");
            else System.out.println("没有"+name+"文件夹");
            return;
        }
        if(a!=null && Objects.equals(a.name, name)){
            flag = true;
            boolean f1 = b == a ? true : false;
            FOLDER nxt = a.nextFolder;
            del(a);
            nowpath.firstChildFolder = nxt;
            if (nxt != null)
                nxt.frontFolder = null;
            if (flag) //同时又是最后一个
                nowpath.lastChildFolder = null;
        }
        else if(b!=null && Objects.equals(b.name, name)){
            flag = true;
            FOLDER pre = b.frontFolder;
            del(pre);
            nowpath.lastChildFolder = pre;
            if (pre != null)
                pre.nextFolder = null;
        }
        else {
            a = a.nextFolder;
            // 递归删除
            while (a != null && a != b && !Objects.equals(a.name, name))
                a = a.nextFolder;
            // 删除最后的文件夹
            if (a != null && Objects.equals(a.name, name))
            {
                flag = true;
                FOLDER pre = a.frontFolder;
                FOLDER nxt = a.nextFolder;
                del(a);
                if (pre != null)
                    pre.nextFolder = nxt;
                if (nxt != null)
                    nxt.frontFolder = pre;
            }
        }
        if(flag) System.out.println("成功删除");
        else System.out.println("没有"+name+"文件夹");
    }
    // 添加文件夹
    void make_directory(String name)
    {
        FOLDER x = nowpath.firstChildFolder;
        FOLDER y = nowpath.lastChildFolder;
        boolean flag = true;
        // 是否有同名的子目录,有同名不让创建
        while (x != y)
        {
            if (Objects.equals(x.name, name)) flag = false;
            x = x.nextFolder;
        }
        if (y != null && Objects.equals(y.name, name))
            flag = false;
        if(!flag)
        {
            System.out.println(name + "文件夹已存在");
            return;
        }
        // 无同名文件夹,开始创建文件夹
        FOLDER newFolder = new FOLDER(name,null,null,
                nowpath,null,null,null,null);
        if(nowpath.firstChildFolder==null){
            nowpath.firstChildFolder = newFolder;
            nowpath.lastChildFolder = newFolder;
        }
        else
        {
            // 更新当前文件夹下的第一个子文件夹和最后一个子文件夹 (链表的形式)
            FOLDER tmp = nowpath.lastChildFolder;
            tmp.nextFolder = newFolder;
            newFolder.frontFolder = tmp;
            nowpath.lastChildFolder = newFolder;
        }
    }
    String getPath()
    {
        String path = nowpath.name+">";
        FOLDER now = nowpath;
        while(now.parentFolder!=null)
        {
            now = now.parentFolder;
            path = now.name +"/"+path;
        }
        return path;
    }
    void Operation(String op,String name)
    {
        if(Objects.equals(op, "exit")){
            System.out.println("操作结束!!!");
            System.exit(0);
        }
        if(Objects.equals(op, "mkdir")) make_directory(name);
        else if(Objects.equals(op, "rmdir")) remove_directory(name);
        else if(Objects.equals(op, "touch")) touch_file(name);
        else if(Objects.equals(op, "rm")) rm(name);
        else if(Objects.equals(op, "cat")) show_context(name);
        else if(Objects.equals(op, "vim")) modify(name);
        else if(Objects.equals(op, "ls")) showInfo();
        else if(Objects.equals(op, "cd")) open_dir(name);
        else System.out.println(op + "命令没找到");
    }

    void menu()
    {
        Scanner in = new Scanner(System.in);
        System.out.println("    创建目录 -- mkdir\n" +
                "    删除目录 -- rmdir\n" +
                "    切换目录 -- cd\n" +
                "    创建文件 -- touch\n" +
                "    删除文件 -- rm\n" +
                "    查看文件内容 -- cat\n" +
                "    写入文件 -- vim\n" +
                "    查看目录 -- ls\n" +
                "    退出系统 -- exit");
        while(true)
        {
            System.out.print(getPath());
            String ss = in.nextLine();
            String[] s = ss.split(" ");
            if(s.length>2) System.out.println("输入有误");
            String op = new String();
            String name = new String();
            op = s[0];
            if(s.length==2 )name = s[1];
            Operation(op,name);
        }
    }

    void createRoot() {//初始化根目录信息
        root=new FOLDER();
        root.frontFolder=null;
        root.nextFolder=null;
        root.parentFolder=null;
        root.firstChildFile=null;
        root.firstChildFolder=null;;
        root.lastChildFile = null;
        root.name="root";
        nowpath = root;
    }
}
class FOLDER{//目录结构
    String name=new String();//目录名
    FOLDER nextFolder;//同级下一目录
    FOLDER frontFolder;//同级上一目录
    FOLDER parentFolder;//父目录
    FOLDER firstChildFolder;//子目录
    FOLDER lastChildFolder;//最后一个子文件夹
    FILE firstChildFile;//子文件
    FILE lastChildFile;

    public FOLDER(String name, FOLDER nextFolder, FOLDER frontFolder, FOLDER parentFolder, FOLDER firstChildFolder, FOLDER lastChildFolder, FILE firstChildFile, FILE lastChildFile)
    {
        this.name = name;
        this.nextFolder = nextFolder;
        this.frontFolder = frontFolder;
        this.parentFolder = parentFolder;
        this.firstChildFolder = firstChildFolder;
        this.lastChildFolder = lastChildFolder;
        this.firstChildFile = firstChildFile;
        this.lastChildFile = lastChildFile;
    }

    public FOLDER() {}
}
class FILE{
    String name=new String();//文件名
    String content=new String();//文件内容
    FILE frontFile;//同级目录上一文件
    FILE nextFile;//同级目录下一文件
    FOLDER parentFolder;//父目录
    public FILE(String name, String content, FILE frontFile, FILE nextFile, FOLDER parentFolder) {
        this.name = name;
        this.content = content;
        this.frontFile = frontFile;
        this.nextFile = nextFile;
        this.parentFolder = parentFolder;
    }
    public FILE() {}
}

C++版本:

#include <bits/stdc++.h>
using namespace std;

struct Folder;
struct File
{
    string name;
    string context;
    int canRead;
    int canWrite;
    File* frontFile;
    File* nextFile;
    Folder* parent;
};

struct Folder
{
    string name;
    int canRead;
    int canWrite;
    Folder* nextFolder;
    Folder* frontFolder;
    Folder* parent;
    Folder* firstChildFolder;
    Folder* lastChildFolder;
    File* firstChildFile;
    File* lastChildFile;
};

Folder* nowpath,* root;

void createroot()
{
    root = new Folder{
        name : "root",
        canRead : 1,
        canWrite : 0,
        nextFolder : nullptr,
        frontFolder : nullptr,
        parent : nullptr,
        firstChildFolder : nullptr,
        firstChildFile : nullptr,
        lastChildFile : nullptr
    };
    nowpath = root;
}

string getpath()  //获取当前文件夹路径
{
    string path = nowpath->name + ">";
    Folder *now = nowpath;
    while (now -> parent != nullptr)
    {
        now = now->parent;
        path = now->name + "/" + path;
    }
    return path;
}

void make_directory(string name) //创建目录
{
    auto x = nowpath->firstChildFolder;
    auto y = nowpath->lastChildFolder;
    bool flag = true;
    while (x != y)
    {
        if (x->name == name)
        flag = false;
        x = x->nextFolder;
    }
    if (y != nullptr && y->name == name)
        flag = false;
    if (!flag) 
    {
        cout << "cannot create directory '" + name + "': Directory exists\n";
        return;
    }
    Folder *newFolder =  new Folder{
        name : name,
        canRead : 1,
        canWrite : 0,
        nextFolder : nullptr,
        frontFolder : nullptr,
        parent : nowpath,
        firstChildFolder : nullptr,
        lastChildFolder : nullptr,
        firstChildFile : nullptr,
        lastChildFile : nullptr
    };
    if (nowpath->firstChildFolder == nullptr)
    nowpath->firstChildFolder = nowpath->lastChildFolder = newFolder;
    else
    {
        auto b = nowpath->lastChildFolder;
        b->nextFolder = newFolder;
        newFolder->frontFolder = b;
        nowpath->lastChildFolder = newFolder;
    }
}

void del(Folder *a) //递归删除a的所有子文件
{
    if (a == nullptr) return;
    auto x = a->firstChildFile;
    auto y = a->lastChildFile;
    while (x != y)
    {
        auto t = x->nextFile;
        free(x);
        x = t;
    }
    if (y != nullptr)
    free(y);

    auto xF = a->firstChildFolder;
    auto yF = a->lastChildFolder;
    while (xF != yF)
    {
        auto t = xF->nextFolder;
        del(xF);
        free(xF);
        xF = t;
    }
    if (yF != nullptr)
    {
        del(yF);
        free(yF);
    }
}

void remove_directory(string name)
{
    bool flag = false;
    auto a = nowpath->firstChildFolder;
    auto b = nowpath->lastChildFolder;
    if (a == nullptr)  goto cc;
    if (a != nullptr && a->name == name)
    {
        flag = true;
        bool fl = b == a ? true : false;
        auto nxt = a->nextFolder;
        del(a);
        free(a);
        nowpath->firstChildFolder = nxt;
        if (nxt != nullptr)
        nxt->frontFolder = nullptr;
        if (flag) //同时又是最后一个
        nowpath->lastChildFolder = nullptr;
    }
    else if (b != nullptr && b->name == name)
    {
        flag = true;
        auto pre = b->frontFolder;
        del(b);
        free(b);
        nowpath->lastChildFolder = pre;
        if (pre != nullptr)
        pre->nextFolder = nullptr;
    }
    else 
    {
        a = a->nextFolder;
        while (a != nullptr && a != b && a->name != name)
        a = a->nextFolder;
        if (a != nullptr && a->name == name)
        {
            flag = true;
            auto pre = a->frontFolder;
            auto nxt = a->nextFolder;
            del(a);
            free(a);
            if (pre != nullptr)
            pre->nextFolder = nxt;
            if (nxt != nullptr)
            nxt->frontFolder = pre;
        }
    }
cc: if (flag)
    cout << "OK\n";
    else cout << "failed to remove '" + name + "' No such directory\n";
}

void touch_file(string name)
{
    auto x = nowpath->firstChildFile;
    auto y = nowpath->lastChildFile;
    bool flag = true;
    while (x != y)
    {
        if (x->name == name)
        flag = false;
        x = x->nextFile;
    }
    if (y != nullptr && y->name == name)
        flag = false;
    if (!flag) 
    {
        cout << "cannot create directory '" + name + "': File exists\n";
        return;
    }
    File * newfile = new File{
        name : name,
        canRead : 1,
        canWrite : 1,
        frontFile : nullptr,
        nextFile : nullptr,
        parent : nowpath
    };
    if (nowpath->firstChildFile == nullptr)
    nowpath->firstChildFile = nowpath->lastChildFile = newfile;
    else
    {
        auto b = nowpath->lastChildFile;
        b->nextFile = newfile;
        newfile->frontFile = b;
        nowpath->lastChildFile = newfile;
    }
}

void rm(string name)
{
    bool flag = false;
    auto a = nowpath->firstChildFile;
    auto b = nowpath->lastChildFile;
    if (a == nullptr) goto cc;
    if (a != nullptr && a->name == name)
    {
        flag = true;
        bool fl = a == b ? true : false;
        auto nxt = a->nextFile;
        free(a);
        nowpath->firstChildFile = nxt;
        if (nxt != nullptr)
        nxt->frontFile = nullptr;
        if (fl)
        nowpath->lastChildFile = nullptr;
    }
    else if (b != nullptr && b->name == name)
    {
        flag = true;
        auto pre = b->frontFile;
        free(b);
        nowpath->lastChildFile = pre;
        if (pre != nullptr)
        pre->nextFile = nullptr;
    }
    else 
    {
        a = a->nextFile;
        while (a != nullptr && a != b && a->name != name)
        a = a->nextFile;
        if (a != nullptr && a->name == name)
        {
            flag = true;
            auto pre = a->frontFile;
            auto nxt = a->nextFile;
            free(a);
            if (pre != nullptr)
            pre->nextFile = nxt;
            if (nxt != nullptr)
            nxt->frontFile = pre;
        }
    }
cc: if (flag)
    cout << "OK\n";
    else cout << "failed to remove '" + name + "' No such file\n";
    
}

void show_context(string name)
{
    auto a = nowpath->firstChildFile;
    auto b = nowpath->lastChildFile;
    while (a != nullptr && a->name != name)
        a = a->nextFile;
    if (a == nullptr || a->name != name)
    {
        cout << "No such file or directory\n";
        return;
    }
    else cout << a->context << '\n';
}

void modify(string name)
{
    auto a = nowpath->firstChildFile;
    auto b = nowpath->lastChildFile;
    while (a != nullptr && a->name != name)
        a = a->nextFile;
    if (a == nullptr || a->name != name)
    {
        cout << "No such file or directory\n";
        return;
    }
    cout << "续写 -r\n覆盖 -w\n";
    string op;
    cin >> op;
    if (op == "-w")
    a->context = "";
    cout << "请输入内容\n";
    getchar();
    getline(cin,op);
    a->context += op;
}

void show()
{
    auto x = nowpath->firstChildFile;
    while (x != nullptr)
    {
        cout << x->name << '\n';
        x = x->nextFile;
    }
    auto xF = nowpath->firstChildFolder;
    while (xF != nullptr)
    {
        cout << xF->name << '\n';
        xF = xF->nextFolder;
    }  
}

void open_dir(string name)
{
    if (name == "..")
    {
        if (nowpath != root)
        nowpath = nowpath->parent;
        return;
    }
    auto a = nowpath->firstChildFolder;
    auto b = nowpath->lastChildFolder;
    while (a != nullptr && a->name != name)
        a = a->nextFolder;
    if (a == nullptr || a->name != name)
    {
        cout << "No such file or directory\n";
        return;
    }
    nowpath = a;
}

void Operation(string op,string name)
{
    if (op == "exit")
    {
        cout << "bye\n";
        exit(0);
    }
    if (op == "mkdir")
    make_directory(name);
    else if (op == "rmdir")
    remove_directory(name);
    else if (op == "touch")
    touch_file(name);
    else if (op == "rm")
    rm(name);
    else if (op == "cat")
    show_context(name);
    else if (op == "vim")
    modify(name);
    else if (op == "ls")
    show();
    else if (op == "cd")
    open_dir(name);
    else cout << op + " : command not found\n";
}

int main()
{
    createroot();
    cout << "创建目录 -- mkdir\n\
    删除目录 -- rmdir\n\
    打开目录 -- cd\n\
    创建文件 -- touch\n\
    删除文件 -- rm\n\
    查看文件 -- cat\n\
    写入文件 -- vim\n\
    列出目录 -- ls\n\
    退出系统 -- exit\n";
    while (1)
    {
        cout << getpath();
        string s,op,name;
        getline(cin,s);
        stringstream ss(s);
        ss >> op >> name;
        Operation(op,name);
    }
    return 0;
}
  • 4
    点赞
  • 30
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值