JAVA——構建以檔案為儲存實體的虛擬物理磁碟類

Starzkg發表於2020-12-30

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使用--建立檔案

相關文章