os实验-Java模拟文件管理

文章目录

    • 内容和数据结构定义
    • code
    • 运行截图

内容和数据结构定义

给出一个磁盘块序列:1、2、3、…、500,初始状态所有块为空的,每块的大小为 2k。选择使用
空闲表、空闲盘区链、位示图三种算法之一来管理空闲块。对于基于块的索引分配执行以下步骤:
(1) 随机生成 2k-10k 的文件 50 个,文件名为 1.txt、 2.txt、 …、50.txt,按照上述算法存储到
模拟磁盘中。
(2) 删除奇数.txt(1.txt、3.txt、…、49.txt)文件
(3) 新创建 5 个文件(A.txt、B.txt、C.txt、D.txt、E.txt),大小为:7k、5k、2k、9k、3.5k,按照与(1)
相同的算法存储到模拟磁盘中。
(4) 给出文件 A.txt、B.txt、C.txt、D.txt、E.txt 的盘块存储状态和所有空闲区块的状态。

File 类定义

public class File {
    public  String fileName;
    public double size; //文件大小/KB
    public int startBlockId;  //起始盘块号
    public int blockNum;   //盘块数

    public File() {}

    public File(String fileName, int startBlockId, double size, int blockNum) {
        this.fileName = fileName;
        this.size = size;
        this.startBlockId = startBlockId;
        this.blockNum = blockNum;
    }

    @Override
    public String toString() {
        return "name =" + fileName + "   size =" + size + "KB    startBlockId =" + startBlockId + "   blockNumber =" + blockNum;
    }
}

Region类定义
程序用空闲盘块表算法来管理空闲块, 所以定义空闲区域 Region 类, 表示空闲表中的一项,

public class Region {
    public int startBlockId;
    public int size;

    public Region(int startBlockId, int size) {
        this.startBlockId = startBlockId;
        this.size = size;
    }


    @Override
    public String toString() {
        return "startBlockId=" + startBlockId + "   size=" + size;
    }
}

code

根据 fileName 和 size 创建文件,根据 size 求出该文件占用的盘块数 s, 再去遍历空闲表 table, 直
到找出一个空闲表中的表项 size>=s, 如果正好相等, 就表示要恰好占用一个表项, 直接从表中移除,
如果大于要求的空间, 则切分表项, 修改表项的 size 大小. 申请到足够空间后, 创建文件对象 file, 并
加入到 map 集合中. 标示出该文件已存在于文件系统中且唯一.

删除操作, 首先从 map 集合中根据 fileName 移除相应的 file 对象, 再释放占用空间. 此时分三种
情况:

  1. 释放的空间与空闲表中某个 Region 范围左邻接, 与该 Region 合并 (Region 表示一块空闲区
    域)
  2. 释放的空间与空闲表中某个 Region 范围右邻接, 与该 Region 合并
  3. 要释放的空间与空闲表中所有表项 Region 不邻接, 直接顺序插入
public class FileOperator {

    private int size;  //磁盘块数 1 to size
    private List<Region> table = new ArrayList<>();  //空闲表
    private Map<String, File> map = new HashMap<>();   //存储文件状态



    public FileOperator(int size) {
        this.size = size;
        table.add(new Region(1, size)); //初始状态, 空闲表只有一项
    }

    /**
     * 创建文件, 更新空闲表数据
     * @param fileName
     * @param size  接收double类型数据, 内部转换成盘块size
     */
    public void create(String fileName, double size) {
        int s = getBlockNum(size);
        for (Region r : table) {
            if (s == r.size) {  //占用一个表项
                File file = new File(fileName, r.startBlockId, size, s);
                map.put(fileName, file);
                table.remove(r);
                return;
            } else if (size < r.size) {  //切分一个表项
                File file = new File(fileName, r.startBlockId, size, s);
                map.put(fileName, file);
                r.startBlockId += s;
                r.size -= s;
                return;
            } else {
                continue;
            }
        }
        //磁盘空间不足
        System.out.println("file: " + fileName + " size: " + size + ": OutOfDiskError");
    }

    /**
     * 删除文件
     * case 1, 与前驱合并
     * case 2, 与后继合并
     * case 3, 插入到相应位置
     * @param fileName
     */
    public void delete(String fileName) {
        File file = map.remove(fileName);
        if (file != null) {
            Region r = new Region(file.startBlockId, file.blockNum);
            insertToTable(r);
        }
    }


    /**
     * 文件大小size到占用盘块数据的映射, 默认盘块大小2K
     * @param size
     * @return
     */
    private int getBlockNum(double size) {
        int s = (int)Math.ceil(size);
        if (s%2 == 0) {
            return s >> 1;
        } else {
            return (s >> 1) + 1;
        }
    }

    public void insertToTable(Region re) {
//        if (re.startBlockId > table.get(table.size() - 1).startBlockId) {  //插入末尾
//            table.add(re);
//            return;
//        }
        //相邻
        for (int i = 0; i < table.size(); i++) {  //相邻处理
            Region r = table.get(i);
            if (r.startBlockId == (re.startBlockId + re.size)) { //re的后继是r的前驱, 与后继合并
                r.size += re.size;
                r.startBlockId = re.startBlockId;
                return;
            } else if (r.startBlockId + r.startBlockId == re.startBlockId) { //r 的后继是re 的前驱, 与前驱合并
                r.size += re.size;
                return;
            } else {
                continue;
            }
        }
        //插入
        table.add(re);
        int sStart = re.startBlockId;
        int sSize = re.size;
        int i = table.size() - 2;
        for (; i >= 0; i--) {
            if (table.get(i).startBlockId > re.startBlockId) {
                Region rr = table.get(i);
                table.get(i + 1).startBlockId = rr.startBlockId;
                table.get(i + 1).size = rr.size;
            } else {
                break;
            }
        }
        table.get(i + 1).startBlockId = sStart;
        table.get(i + 1).size = sSize;
    }

    public void printTable() {
        System.out.println("空闲区块:  ");
        for (Region r : table) {
            System.out.println(r.toString());
        }
    }

    /**
     *
     * @param fileName
     */
    public void printAttribute(String fileName) {
        if (map.containsKey(fileName)) {
            System.out.println(map.get(fileName));
        }
    }
    public void printAttribute() {
        System.out.println("文件存储状态(乱序): ");
        Set<String> files = map.keySet();
        for (String file : files) {
            System.out.println(map.get(file).toString());
        }
    }
}

运行截图

    public static void main(String[] args) {
        FileOperator fo = new FileOperator(500);
        
        //随机生成50个文件
        for (int i = 0; i < 50; i++) {
            fo.create(i + ".txt", ((int)(((Math.random()*8) + 2)*100)/100.0));
        }
     //  删除奇数文件
        for (int i = 1; i < 50; i += 2) {
            fo.delete(i + ".txt");
        }
        //新建文件
        fo.create("A.txt", 7);
        fo.create("B.txt", 5);
        fo.create("C.txt", 2);
        fo.create("D.txt", 9);
        fo.create("E.txt", 3.5);

        //查询文件状态
        System.out.println("ABCDE文件状态: ");
        fo.printAttribute("A.txt");
        fo.printAttribute("B.txt");
        fo.printAttribute("C.txt");
        fo.printAttribute("D.txt");
        fo.printAttribute("E.txt");

        System.out.println();
        fo.printTable();

        fo.printAttribute();
    }

os实验-Java模拟文件管理_第1张图片

os实验-Java模拟文件管理_第2张图片

代码下载: https://download.csdn.net/download/weixin_41889284/11253284

你可能感兴趣的:(os)