java语言实现操作系统中的文件管理系统

123.jpg
123.jpg

Basic Framework

屏幕快照 2017-12-08 11.38.25.png
屏幕快照 2017-12-08 11.38.25.png

fileModel.java

package File_System_Structure;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;

public class fileModel {
//fileModel类用来记录文件或目录的相关属性

    public Map<String, fileModel> subMap = new HashMap<String, fileModel>();
    private String name; //文件名或目录名
    private String type; //文件类型
    private int attr; //用来识别是文件还是目录 
    private int startNum;   //在FAT表中起始位置
    private int size;   //文件的大小
    private fileModel father = null;    //该文件或目录的上级目录
    
    public fileModel( String name, String type, int startNum, int size ){
        this.name = name;
        this.type = type;
        this.attr = 2;
        this.startNum = startNum;
        this.size = size;       
    }
    
    public fileModel( String name, int startNum ) {
        this.name = name;
        this.attr = 3;
        this.startNum = startNum;
        this.type = "  ";
        this.size = 1;
    }
    
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public String getType() {
        return type;
    }
    public void setType(String type) {
        this.type = type;
    }
    public int getAttr() {
        return attr;
    }
    public void setAttr(int attr) {
        this.attr = attr;
    }
    public int getStartNum() {
        return startNum;
    }
    public void setStartNum(int startNum) {
        this.startNum = startNum;
    }
    public int getSize() {
        return size;
    }
    public void setSize(int size) {
        this.size = size;
    }

    public fileModel getFather() {
        return father;
    }

    public void setFather(fileModel father) {
        this.father = father;
    }

}

OSManager.java

package File_System_Structure;

import java.util.HashMap;
import java.util.Map;
import java.util.Map.Entry;

public class OSManager {
    //OSManager这个类实现对文件的各种操作

    public Map<String, fileModel> totalFiles = new HashMap<String, fileModel>();
    //定义FAT表
    private int[] fat = new int[128]; 
    //创建根目录 使用fat表的第一项
    private fileModel root = new fileModel("root", 1);
    private fileModel nowCatalog = root;
    
    public OSManager() {
        //将FAT表初始化全部为0,并将第一位设为根目录的空间
        for( int i = 0; i < fat.length ; i++ ) {
            fat[i] = 0;
        }
        fat[ 1 ] = 255; //255表示磁盘块已占用
        fat[ 0 ] = 126; //纪录磁盘剩余块数  
        root.setFather( root );
        totalFiles.put( "root", root );
    }
    
    public int setFat(int size) {
        int[] startNum = new int[128];
        int i = 2; //纪录fat循环定位
        for( int j = 0; j < size; i++ ) {
            if( fat[ i ] == 0 ) {
                startNum[ j ] = i; //纪录该文件所有磁盘块
                if( j > 0 ) {
                    fat[ startNum[ j-1 ] ] = i; //fat上一磁盘块指向下一磁盘块地址
                }
                j++;
            }
        }
        fat[ i-1 ] = 255;
        return startNum[ 0 ]; //返回该文件起始块盘号
    }


    /*
     * 
     * 该方法用于删除时释放FAT表的空间
     */
    public void deleteFAT( int startNum ) {
        int nextPoint = fat[ startNum ];
        int nowPoint = startNum;
        int count = 0;
        while( fat[nowPoint ] != 0 ) {
            nextPoint = fat[ nowPoint ];
            if( nextPoint == 255 ) {
                fat[ nowPoint ] =0;
                count++;
                break;
            } else {
                fat[ nowPoint ] = 0;
                count++;
                nowPoint = nextPoint;
            }
        }
        fat[0] += count;
    }
    

    /*
     * 
     * 以下为追加内容时修改fat表
     * 
     */
    public void AddFAT(int startNum, int addSize) {
        int nowPoint = startNum;
        int nextPoint = fat[startNum];
        while( fat[ nowPoint ] != 255 ) {
            nowPoint = nextPoint;
            nextPoint = fat[ nowPoint ];
        }//找到该文件终结盘块

        for( int i = 2, count = 0; count < addSize; i++ ) {
            if( fat[ i ] == 0 ) {
                fat[ nowPoint ] = i;
                nowPoint = i;
                count++;
                fat[ nowPoint ] = 255;//作为当前文件终结盘块
            }
        }
    }
    
    /*
     *  以下为创建文件和目录方法
     * 
     */
    public void createFile( String name, String type, int size ) {
        
        if( fat[ 0 ] >= size ) {    //判断磁盘剩余空间是否足够建立文件
            fileModel value = nowCatalog.subMap.get( name ); //该目录下是否寻找同名目录或文件
            if( value != null ) {  //判断该文件是否存在
                if( value.getAttr() == 3 ) {   //若存在同名目录 继续创建文件
                    int startNum = setFat( size ); 
                    fileModel file = new fileModel( name, type, startNum, size );
                    file.setFather( nowCatalog ); //纪录上一层目录
                    nowCatalog.subMap.put( name, file ); //在父目录添加该文件
                    totalFiles.put( file.getName(), file );
                    fat[ 0 ] -= size;
                    System.out.println( "File is successfully created!" );
                    showFile();
                } else if( value.getAttr() == 2 ) { //若同名文件已存在,创建失败
                    System.out.println("File fails to create because the file already exists"); 
                    showFile();
                }
            } else if( value == null ) { //若无同名文件或文件夹,继续创建文件
                int startNum = setFat( size ); 
                fileModel file = new fileModel( name, type, startNum, size );
                file.setFather( nowCatalog ); //纪录上一层目录
                nowCatalog.subMap.put( name, file ); //在父目录添加该文件
                totalFiles.put( file.getName(), file );
                fat[0] -= size;
                System.out.println( "File is successfully created!");
                showFile();
                }
        } else {
            System.out.println("File fails to create because insufficient disk space!");
        }
    
    }
    
    public void createCatolog( String name ) {
        
        if( fat[ 0 ] >= 1 ) { //判断磁盘空间是否足够创建文件夹
            
            fileModel value = nowCatalog.subMap.get( name ); //判断该目录下是否存在同名目录或文件
            if( value != null ) {
                if( value.getAttr() == 2 ) {
                    int startNum = setFat( 1 );
                    fileModel catalog = new fileModel( name, startNum );
                    catalog.setFather( nowCatalog ); //纪录上一层目录
                    nowCatalog.subMap.put( name, catalog );
                    fat[ 0 ]--;
                    totalFiles.put( catalog.getName(), catalog );
                    System.out.println( "Directory is successfully created!" );
                    showFile();
                } 
                else if(value.getAttr() == 3) {
                    System.out.println( "Directory fails to create because the directory already exists!" );
                    showFile();
                } 
            } 
            else if(value == null) {
                int startNum = setFat(1);
                fileModel catalog = new fileModel( name, startNum );
                catalog.setFather( nowCatalog ); //纪录上一层目录
                nowCatalog.subMap.put( name, catalog );
                fat[ 0 ]--;
                totalFiles.put( catalog.getName(), catalog );
                System.out.println( "Directory is successfully created!" );
                showFile();
            }           
        } 
        else {
            System.out.println("Directory fails to create because insufficient disk space!");
        }
    }
    
    
    /*
     * 
     * 以下为显示该目录下的所有文件信息
     * 
     */
    public void showFile() {
        System.out.println("***************** < " + nowCatalog.getName() + " > *****************");
       
        if( !nowCatalog.subMap.isEmpty() ) {
            for( fileModel value : nowCatalog.subMap.values() ) {
                if(value.getAttr() == 3) { //目录文件
                    System.out.println("File Name:" + value.getName());
                    System.out.println("Operation Type:" + "Folder");
                    System.out.println("Starting Disk Blocks:" + value.getStartNum());
                    System.out.println("Size: " + value.getSize());
                    System.out.println("<-------------------------------------->");
                }
                else if(value.getAttr() == 2) {
                    System.out.println("File Name:" + value.getName() + "." + value.getType());
                    System.out.println("Operation Type: " + "Readable & Writable File");
                    System.out.println("Starting Disk Blocks:" + value.getStartNum());
                    System.out.println("Size:" + value.getSize());
                    System.out.println("<-------------------------------------->");
                }
            }
        }
        for(int i =0; i<2; i++) 
        System.out.println();
        System.out.println("Disk Surplus Space:" + fat[ 0 ] + "            " + "Exit the system please enter:exit");
        System.out.println();
    }

    /*
     * 
     * 以下为删除该目录下某个文件
     * 
     */
    public void deleteFile(String name) {
        
        fileModel value = nowCatalog.subMap.get( name );
        if( value == null ) {
            System.out.println("Delete failed, No File or Folder!!");
        } 
        else if( !value.subMap.isEmpty() ){
            System.out.println("Delete failed because the folder contains files!");
        } 
        else {
            nowCatalog.subMap.remove(name);
            deleteFAT(value.getStartNum());
            if(value.getAttr() == 3) {
                System.out.println("Folder " + value.getName() + " Have been successfully deleted");
                showFile();
            } 
            else if(value.getAttr() == 2) {
                System.out.println("File " + value.getName() + "Have been successfully deleted");
                showFile();
            }
        }
    }
    
    /*
     * 
     * 以下为文件或文件夹重命名方法
     * 
     */
    public void reName(String name, String newName) {
        if( nowCatalog.subMap.containsKey(name) ) {
            if( nowCatalog.subMap.containsKey( newName ) ) {
                System.out.println("Rename failed because the same name file already exists!"); 
                showFile();
            } 
            else {
                fileModel value = nowCatalog.subMap.get( name );
                value.setName( newName );
                nowCatalog.subMap.remove( name );
                nowCatalog.subMap.put( newName, value );
                System.out.println( "Rename has succeed" );
                System.out.println();
                showFile();
            }
        } 
        else {
            System.out.println("Rename failed because there is no this file");
            showFile();
        }
    }
    
    /*
     * 
     * 以下为修改文件类型
     * 修改类型需要打开文件后才能操作
     */
    public void changeType( String name, String type ) {
        
        nowCatalog = nowCatalog.getFather();
        if( nowCatalog.subMap.containsKey( name ) ) {
            fileModel value = nowCatalog.subMap.get( name );
            if(value.getAttr() == 2){
                value.setType(type);
                nowCatalog.subMap.remove(name);
                nowCatalog.subMap.put(name, value);
                System.out.println("Modify type success!");
                showFile();
            } 
            else if(value.getAttr() == 3) {
                System.out.println("Change error because the folder can not modify type!!");
                openFile( value.getName() );
            }
        } 
        else {
            System.out.println("Modify error, please check whether the input file name is correct!");
        }
    }
    
    /*
     * 以下为打开文件或文件夹方法
     * 
     */
    public void openFile( String name ) {
        if( nowCatalog.subMap.containsKey( name ) ) {
            fileModel value = nowCatalog.subMap.get(name);
            if(value.getAttr() == 2) {
                nowCatalog = value;
                System.out.println("The file has been opened and the file size is: " + value.getSize() );               
            }
            else if(value.getAttr() == 3) {
                nowCatalog = value;
                System.out.println("The file has been opened!");
                showFile();
            }
        } 
        else{
            System.out.println("Open failed because the file does not exist!");
        }
    }
    

    /*
     * 
     * 以下为向文件追加内容方法
     * 追加内容需要打开文件后才能操作
     */
    public void reAdd(String name, int addSize){
        if( fat[0] >= addSize ) {
            nowCatalog = nowCatalog.getFather();
            if(nowCatalog.subMap.containsKey(name)) {
                fileModel value = nowCatalog.subMap.get(name);
                if(value.getAttr() == 2) {
                    value.setSize(value.getSize() + addSize);
                    AddFAT(value.getStartNum(), addSize);
                    System.out.println("Addition content is successful! The file is being reopened...");
                    openFile(name);
                } 
                else{
                    System.out.println("The appended content failed, please verify that the filename is entered correctly.");                   
                }
            }
        }
        else{
            System.out.println("Addition content is failed because insufficient memory space");
            }
        }
    
    
    /*
     * 
     * 以下为返回上一层目录
     * 
     */
    public void backFile() {
        if(nowCatalog.getFather() == null) {
            System.out.println("The document does not have a superior directory!");
        } else {
            nowCatalog = nowCatalog.getFather();
            showFile();
        }
    }
    
    /*
     * 以下根据绝对路径寻找文件
     * 
     */
    public void searchFile(String[] roadName) {
        
        fileModel theCatalog = nowCatalog; //设置断点纪录当前目录
        
        if( totalFiles.containsKey(roadName[roadName.length-1]) ) { //检查所有文件中有无该文件
            nowCatalog = root; //返回根目录
            if( nowCatalog.getName().equals( roadName[0]) ) {   //判断输入路径的首目录是否root
                System.out.println("yes");
                for( int i = 1; i < roadName.length; i++ ) {
                    if( nowCatalog.subMap.containsKey( roadName[ i ] ) ) {
                        nowCatalog = nowCatalog.subMap.get( roadName[ i ] ); //一级一级往下查

                    } 
                    else {
                        System.out.println("Can't find the file or directory under this path, please check whether the path is correct!");
                        nowCatalog = theCatalog;
                        showFile();
                        break;
                    }
                }
                if( roadName.length > 1 ){
                    nowCatalog = nowCatalog.getFather(); //返回文件上一级目录 
                    showFile();
                }
            } 
            else{
                nowCatalog = theCatalog;
                System.out.println("Please enter the correct absolute path!");
                showFile();
            }
        } 
        else{
            System.out.println("This file or directory does not exist, please enter the correct absolute path!");
            showFile();
        }
    }
    
    /*
     * 以下为打印FAT表内容
     * 
     */
    public void showFAT() {

        for(int j=0; j<125; j+=5) {
            System.out.println("第几项 | " + j + "        " + (j+1) + "        " + (j+2) + "        "
                    + (j+3) + "        " + (j+4));
            System.out.println("内容 | " + fat[j] + "        " + fat[j+1] + "        " + fat[j+2]
                     + "        " + fat[j+3] + "        " + fat[j+4]);
            System.out.println();
        }
        int j = 125;
        System.out.println("第几项 | " + j + "        " + (j+1) + "        " + (j+2));
        System.out.println("内容 | " + fat[j] + "        " + fat[j+1] + "        " + fat[j+2]);
        System.out.println();
        showFile();
    }
}

testFileSystem.java

package File_System_Structure;

import java.util.ArrayList;
import java.util.Scanner;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class testFileSystem {
    public static void main(String[] args) {
        try{
            OSManager manager = new OSManager();
            meun(manager);
            }
        catch (Exception e){
            e.printStackTrace();
        }
    }

    public static void meun(OSManager manager) {
        Scanner s = new Scanner(System.in);
        String str = null;
        System.out.println("***********" + "Welcome to use the file simulation operating system" + "***********");
        System.out.println();
        manager.showFile();

        System.out.println("Please enter command line(Enter help to view the command table):");
        while ((str = s.nextLine()) != null) {
            if (str.equals("exit")) {
                System.out.println("Thank you!");
                break;
            }

            String[] strs = editStr(str);
            switch (strs[0]) {
            case "createFile":
                if (strs.length < 4) {
                    System.out.println("The command you have entered is incorrect. Please check it.");
                } 
                else {
                    manager.createFile(strs[1], strs[2],
                            Integer.parseInt(strs[3]));
                    }
                break;
            case "createCatalog":
                if (strs.length < 2) {
                    System.out.println("The command you have entered is incorrect. Please check it.");
                } 
                else {
                    manager.createCatolog(strs[1]);
                    }
                break;
            case "open":
                if (strs.length < 2) {
                    System.out.println("The command you have entered is incorrect. Please check it.");
                } 
                else {
                    manager.openFile(strs[1]);
                    }
                break;
            case "cd":
                if (strs.length < 2) {
                    System.out.println("The command you have entered is incorrect. Please check it.");
                } 
                else {
                    manager.openFile(strs[1]);
                    }
                break;
            case "cd..":
                manager.backFile();
                break;
            case "delete":
                if (strs.length < 2) {
                    System.out.println("The command you have entered is incorrect. Please check it.");
                } 
                else {
                    manager.deleteFile(strs[1]);
                    }
                break;
            case "rename":
                if (strs.length < 3) {
                    System.out.println("The command you have entered is incorrect. Please check it.");
                } 
                else {
                    manager.reName(strs[1], strs[2]);
                    }
                break;
            case "search": {
                if (strs.length < 2) {
                    System.out.println("The command you have entered is incorrect. Please check it.");
                } 
                else {
                    String[] roadName = strs[1].split("/");
                    manager.searchFile(roadName);
                    }
                break;
            }
            case "showFAT":
                manager.showFAT();
                break;
            case "addContents":
                if (strs.length < 3) {
                    System.out.println("The command you have entered is incorrect. Please check it.");
                } 
                else {
                    manager.reAdd(strs[1], Integer.parseInt(strs[2]));
                    }
                break;
            case "changeType":
                if (strs.length < 3) {
                    System.out.println("The command you have entered is incorrect. Please check it.");
                } else {
                    manager.changeType(strs[1], strs[2]);
                }
                break;
            case "help": {
                System.out.println("The commands are as follows(Space cannot be omitted):");
                System.out
                        .println("createFile FileName fileType fileSize");
                System.out.println("<Create a file, for instance:createFile PUSU txt 5 >");
                System.out.println();
                System.out
                        .println("createCatalog FatalogName");
                System.out.println("<Create a directory, for instance:createCatalog myFile >");
                System.out.println();
                System.out
                        .println("open Name.FileTypt");
                System.out.println("<Open a file, for instance:open PUSU.txt >");
                System.out.println();
                System.out.println("cd CatalogName");
                System.out.println("<Open a directory, for instance: cd myFile >");
                System.out.println();
                System.out.println("cd..");
                System.out.println("<Return to the superior directory, for instance: cd..");
                System.out.println();
                System.out
                        .println("delete FileName/CatalogName");
                System.out.println("<Delete a files or a directory (the directory must be empty), for instance:delete PUSU >");
                System.out.println();
                System.out
                        .println("rename FileName/CatalogName NewName");
                System.out.println("<rename a file or a directory, for instance: rename myfile mycomputer >");
                System.out.println();
                System.out
                        .println("search FileAbsolutedRoad/CatalogAbsolutedRoad");
                System.out.println("<Finding a file or directory based on an absolute path, for instance: search root/marco >");
                System.out.println();
                System.out.println("showFAT");
                System.out.println("<Look at the FAT table, for instance: showFAT>");
                System.out.println();
                System.out.println();
                System.out.println("The following command needs to open the file before:");
                System.out
                        .println("addContents FileName ContentSize");
                System.out.println("<Add content to a file, for instance:ddContents PUSU 4 >");
                System.out.println();
                System.out
                        .println("changeType FileName newType");
                System.out.println("<Change file type, for instance: changeType PUSU doc>");
                System.out.println();
                break;
            }
            default:
                for(String st : strs)
                    System.out.println(st);
                System.out.println("The command you have entered is incorrect. Please check it.");
            }
            System.out.println("Please enter command line(Enter help to view the command table)::");
        }
    }

    public static String[] editStr(String str) {
        Pattern pattern = Pattern.compile("([a-zA-Z0-9.\\\\/]*) *");// 根据空格分割输入命令
        Matcher m = pattern.matcher(str);
        ArrayList<String>  list = new ArrayList<String>();
        while(m.find()){
            list.add(m.group(1));
        }
        String[] strs = list.toArray(new String[list.size()]);
        
        for (int i = 1; i < strs.length; i++) { // 判断除命令以外每一个参数中是否含有 "."
            int j = strs[i].indexOf(".");
            if (j != -1) { // 若含有"." 将其切割 取前部分作为文件名
                String[] index = strs[i].split("\\."); // 使用转义字符"\\."
                strs[i] = index[0];
            }
        } 
        return strs;
    }

}

Running Effect

屏幕快照 2017-12-08 11.35.56.png
屏幕快照 2017-12-08 11.35.56.png

屏幕快照 2017-12-08 11.36.09.png
屏幕快照 2017-12-08 11.36.09.png

屏幕快照 2017-12-08 11.36.30.png
屏幕快照 2017-12-08 11.36.30.png

屏幕快照 2017-12-08 11.36.40.png
屏幕快照 2017-12-08 11.36.40.png

Source Download

Please click the address->File System Structure

Summarize

用java语言模拟操作系统中的文件管理系统,文件模拟磁盘,数组模拟缓冲区,其中:

  1. 支持多级目录结构,支持文件的绝对读路径;
  2. 文件的逻辑结构采用流式结构,物理结构采用链接结构中的显式链接方式;
  3. 采用文件分配表FAT;
  4. 实现的命令包括建立目录、列目录、删除空目录、建立文件、删除文件、显示
    文件内容、打开文件、读文件、写文件、关闭文件、改变文件属性。可以采用
    命令行界面执行这些命令,也可以采用“右击快捷菜单选择”方式执行命令。
  5. 后编写主函数对所作工作进行测试。

原文地址:www.iooy.com

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 194,457评论 5 459
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 81,837评论 2 371
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 141,696评论 0 319
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 52,183评论 1 263
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 61,057评论 4 355
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 46,105评论 1 272
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 36,520评论 3 381
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 35,211评论 0 253
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 39,482评论 1 290
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 34,574评论 2 309
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 36,353评论 1 326
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 32,213评论 3 312
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 37,576评论 3 298
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 28,897评论 0 17
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,174评论 1 250
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 41,489评论 2 341
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 40,683评论 2 335

推荐阅读更多精彩内容