signed

QiShunwang

“诚信为本、客户至上”

JAVA——构建以文件为存储实体的虚拟物理磁盘类

2020/12/30 6:03:04   来源:

Maven

        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <optional>true</optional>
        </dependency>
        <dependency>
            <groupId>org.slf4j</groupId>
            <artifactId>slf4j-log4j12</artifactId>
        </dependency>
        <dependency>
            <groupId>org.junit.platform</groupId>
            <artifactId>junit-platform-launcher</artifactId>
            <version>1.7.0</version>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>org.junit.jupiter</groupId>
            <artifactId>junit-jupiter-engine</artifactId>
            <version>5.7.0</version>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>org.junit.vintage</groupId>
            <artifactId>junit-vintage-engine</artifactId>
            <version>5.7.0</version>
            <scope>test</scope>
        </dependency>

解决方案

package cn.edu.zstu.fms.storage;

import lombok.Data;
import lombok.extern.slf4j.Slf4j;

import java.io.*;

/**
 * @author ShenTuZhiGang
 * @version 1.0.0
 * @date 2020-12-30 00:46
 */
@Data
@Slf4j
public class PhysicalVirtualDisk extends MyVirtualDick {
    /**
     *
     */
    private static final long serialVersionUID = 1L;
    /**
     * 虚拟磁盘目录
     */
    private static final String VIRTUAL_DISK_FILE_PATH = "." + File.separator + "dir" + File.separator + "pvd";
    /**
     * 虚拟磁盘文件
     */
    private File file=new File(VIRTUAL_DISK_FILE_PATH);
    /**
     *
     */
    private RandomAccessFile data = null;
    /**
     * 运用单例模式得到当前磁盘实例
     *
     */
    private static PhysicalVirtualDisk disk = new PhysicalVirtualDisk();
    {
        this.SECTOR_SUM = 1024;
        this.SECTOR_BYTE_NUM = 512;
        this.MEDIA_DESCRIPTOR = (byte)0xF8;
    }
    private PhysicalVirtualDisk() {
        log.info("物理磁盘初始化");

        if(!file.exists()){
            log.info("The file system doesn't exist, and then it will be created by format().");
            try {
                File fileParent = file.getParentFile();//返回的是File类型,可以调用exsit()等方法
                if((fileParent.exists() || fileParent.mkdirs()) && file.createNewFile()){
                    //this.data = new RandomAccessFile(file,"rw");
                    DiskBlock whiteBlock = new DiskBlock();
                    whiteBlock.setData(new byte[SECTOR_BYTE_NUM]);
                    for(int i=0; i<SECTOR_SUM; i++){
                        this.set(i,whiteBlock);
                    }
                    log.info("虚拟物理磁盘创建成功");
                }else {
                    log.error("虚拟物理磁盘创建失败");
                    throw new RuntimeException("虚拟物理磁盘创建失败");
                }
            } catch (IOException e) {
                log.error("虚拟物理磁盘创建失败");
                e.printStackTrace();
            }
        }
        log.info("虚拟物理磁盘加载完成");
    }
    public static synchronized PhysicalVirtualDisk getInstance() {
        return disk;
    }
    /**
     * 获取磁盘块
     * @param id 磁盘块号
     * @return 磁盘块
     */
    @Override
    public synchronized DiskBlock get(int id) throws IOException {
        byte[] res = new byte[SECTOR_BYTE_NUM];
        try {
            log.info("正在读取第【" + id+ "】扇区");
            this.data = new RandomAccessFile(file,"r");
            this.data.seek(id * SECTOR_BYTE_NUM);
            this.data.read(res);
        } catch (FileNotFoundException e) {
            log.error("虚拟物理磁盘文件不存在");
            e.printStackTrace();
            return null;
        }finally {
            if(this.data != null){
                try {
                    this.data.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
        DiskBlock block = new DiskBlock();
        block.setData(res);
        return block;
    }

    /**
     * 保存磁盘块
     * @param id 磁盘块号
     * @param block 磁盘块
     * @return 是否保存成功
     */
    @Override
    public synchronized Boolean set(int id ,DiskBlock block) throws IOException {
        try {
            log.info("正在写入第【" + id+ "】扇区");
            this.data = new RandomAccessFile(file,"rw");
            this.data.seek(id * SECTOR_BYTE_NUM);
            this.data.write(block.getData());
        } catch (FileNotFoundException e) {
            log.error("虚拟物理磁盘文件不存在");
            e.printStackTrace();
            return false;
        }finally {
            if(this.data != null){
                try {
                    this.data.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
        return true;
    }
}
package cn.edu.zstu.fms.storage;

import java.io.IOException;
import java.io.Serializable;

/**
 * @author ShenTuZhiGang
 * @version 1.0.0
 * @date 2020-12-30 02:27
 */
public abstract class MyVirtualDick implements Serializable {
    private static final long serialVersionUID = 1L;
    /**
     * 扇区总数
     */
    public Integer SECTOR_SUM = 1024;
    /**
     * 每扇区字节数
     */
    public Short SECTOR_BYTE_NUM = 512;
    /**
     * 介质描述符
     */
    public Byte MEDIA_DESCRIPTOR = (byte)0xF8;

    abstract DiskBlock get(int id) throws IOException;
    abstract Boolean set(int id ,DiskBlock block) throws IOException;
}

 

参考文章

Java中File使用--创建文件