自定义文件存储

       我们知道文件存储可以存储一些数据,我们现在想要利用文件存储的方法, * 来构建一类类似于redis的持久化存储类。

* 它可以存储不同类型的对象,并且可以设置过期时间,

* 当过期时间到达时,对象会被自动删除或不可访问。

* 注意,这里的存储对象期望可以是尽可能支持广泛类型的对象, 而不仅仅是特定的类型的对象。 实现以下问题的方法很多,并没有唯一答案, 我们重点关注代码的可读性和可维护性及思路。

package com.yupi.autoreply.monitor;

import lombok.ToString;

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

/**
 * 面试题:我们知道文件存储可以存储一些数据,我们现在想要利用文件存储的方法,
 * 来构建一类类似于redis的持久化存储类。
 * 它可以存储不同类型的对象,并且可以设置过期时间,
 * 当过期时间到达时,对象会被自动删除或不可访问。
 * 注意,这里的存储对象期望可以是尽可能支持广泛类型的对象,
 * 而不仅仅是特定的类型的对象。
 * 提示:实现以下问题的方法很多,并没有唯一答案,请尽可能提供简洁的实现。
 * 我们重点关注代码的可读性和可维护性及思路。
 * 提交格式:请提供实现的代码,并且提供运行结果的截图。
 */

public class DataSave {

    // 存储key-value对应关系的Map
    private Map<String, Long> keysExpireTimeMap = new HashMap<>();

    private Map<String, Serializable> keyValuesMap = new HashMap<>();

    // 文件路径
    private static final String FILE_PATH = "data_save_file.dat";

    /**
     * 请实现持久化存储函数(使用文件存储相关方法)
     *
     * @param key    存储的key
     * @param s      存储的对象
     * @param expire 过期时间,单位秒,如果为0则表示永不过期
     */
    void save(String key, Serializable s, int expire) {
        // 存储key-value对应关系
        keyValuesMap.put(key, s);
        // 设置过期时间
        if (expire > 0) {
            long expireTime = System.currentTimeMillis() + expire * 1000;
            keysExpireTimeMap.put(key, expireTime);
        }
        // 将key-value对应关系保存到文件中
        saveToFile();
    }

    /**
     * 请实现持久化数据的取出
     *
     * @param key 存储的key
     * @return 存储的对象
     */

    Object load(String key) {
        Serializable value = keyValuesMap.get(key);
        // 当value为空或者key已经过期时,返回null
        if (value == null || (keysExpireTimeMap.containsKey(key) &&
                keysExpireTimeMap.get(key) < System.currentTimeMillis())) {
            return null;
        }
        return value;
    }

    /**
     * 将key-values对应关系存储到文件中
     */
    private void saveToFile() {
        try (ObjectOutputStream out = new ObjectOutputStream(new FileOutputStream(FILE_PATH))) {
            out.writeObject(keyValuesMap);
            out.writeObject(keysExpireTimeMap);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    /**
     * 从文件中加载key-values对应关系
     */
    @SuppressWarnings("unchecked")
    private void loadFromFile() {
        try (ObjectInputStream in = new ObjectInputStream(new FileInputStream(FILE_PATH))) {
            keyValuesMap = (Map<String, Serializable>) in.readObject();
            keysExpireTimeMap = (Map<String, Long>) in.readObject();
        } catch (IOException | ClassNotFoundException e) {
            e.printStackTrace();
        }
    }

    public static void main(String[] args) {
        // 初始化并加载数据
        DataSave dataSave = new DataSave();
        dataSave.loadFromFile();
        School sc = new School("wuhan", "wuhan location");
        Clazz c = new Clazz("1", 30, 2, sc);
        Student s = new Student("zhangsan", 18, c);
        Student s0 = new Student("lisi", 22, c);
        // 存储和取出学生对象
        dataSave.save("student", s, 0);
        Student s2 = (Student) dataSave.load("student");
        if (s2 != null) {
            System.out.println("age:" + s2.age);
            System.out.println("grade:" + s2.clazz.grade);
            System.out.println("address:" + s2.clazz.school.address);
        }

        // 存储和取出班级对象
        dataSave.save("clazz", c, 0);
        Clazz c2 = (Clazz) dataSave.load("clazz");
        if (c2 != null) {
            System.out.println("grade:" + c2.grade);
            System.out.println("address:" + c2.school.address);
        }

        // 存储和取出学校对象
        dataSave.save("school", sc, 0);
        School sc2 = (School) dataSave.load("school");
        if (sc2 != null) {
            System.out.println("address:" + sc2.address);
        }

        // 存储和取出学生列表
        ArrayList<Student> students = new ArrayList<>();
        students.add(s);
        students.add(s0);
        dataSave.save("students", students, 0);
        ArrayList students2 = (ArrayList) (dataSave.load("students"));
        if (students2 != null) {
            System.out.println("students size:" + students2.size());
            System.out.println("students1 age:" + ((Student) students2.get(0)).age);
        }

        // 存储和取出学生对象,过期时间为10秒
        dataSave.save("school_test", sc, 10);
        School sc3 = (School) (dataSave.load("school_test"));
        if (sc3 != null) {
            System.out.println("未过期时,school:" + sc3);
        }

        try {
            Thread.sleep(10000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        School sc4 = (School) (dataSave.load("school_test"));
        System.out.println("已过期时,school:" + (sc4 == null));
    }
}

@ToString
class Student implements Serializable {

    String name;
    int age;
    Clazz clazz;

    public Student(String name, int age, Clazz clazz) {
        this.name = name;
        this.age = age;
        this.clazz = clazz;
    }
}

@ToString
class Clazz implements Serializable {
    String grade;
    int studentNumbers;
    int teacherNumbers;
    School school;

    public Clazz(String grade, int studentNumbers, int teacherNumbers, School school) {
        this.grade = grade;
        this.studentNumbers = studentNumbers;
        this.teacherNumbers = teacherNumbers;
        this.school = school;
    }
}

@ToString
class School implements Serializable {
    String name;
    String address;
    public School(String name, String address) {
        this.name = name;
        this.address = address;
    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值