缓存对象到文件和从文件获取对象 冷不防 2023-03-01 12:30 39阅读 0赞 ### 背景 ### 我们在工作中可能会遇到这样的场景,我们需要定时获取获取一个对象。但这个对象比较大,数量比较多。缓存在redis,数据库里面都不太合适。这个时候我们可以考虑将文件缓存本地文件当中。 ### 代码 ### 1、配置文件文件缓存路径 在application.properties中添加 fileCacheDir=C:\\Users\\Administrator\\Desktop\\deploy 2、设置文件缓存路径 @Configuration public class FileCacheConfig { @Value("${fileCacheDir}") private String fileCacheDir; @Bean public FileCache getFileCache(){ return new FileCache(fileCacheDir); } } 3、操作文件缓存对象 接口 public interface ICache { /** * 根据key获取缓存数据 * @param key 存储key * @return 缓存到文件中的数据 */ <T> T get(String key) throws IOException, ClassNotFoundException, Exception; /** * 添加缓存 * @param key 存储key * @param data 缓存到文件中的数据 */ int set(String key, Object data) throws IOException; /** * 删除 * @return 删除影响的行数 */ int delete(String key); } 具体操作类: public class FileCache implements ICache { private String cacheDir; public FileCache(String cacheDir) { this.cacheDir = cacheDir; } @Override public Object get(String key) throws Exception { File file = new File(this.getRealFilePath(key)); if (!file.exists()) { return null; } //获取文件中对象 Object fileObject = FileOperate.getFileObject(file); Object fileStorageObject = null; if ( fileObject instanceof FileCacheObject) { FileCacheObject fcObject = (FileCacheObject)fileObject; //查看缓存是否过期 if (!fcObject.isCacheExpire()) { fileStorageObject = fcObject.getStorageObject(); } } //如果不存在活已经过期就删除 if (null == fileStorageObject) { file.delete(); } return fileStorageObject; } @Override public int set(String key, Object data) throws IOException { String filePath = this.getRealFilePath(key); return FileOperate.saveObjectToFile(filePath, new FileCacheObject(data)) ? 1 : 0; } @Override public int delete(String key) { String filePath = this.getRealFilePath(key); File file = new File(filePath); if (!file.exists()) { return 1; }else { return file.delete() ? 1 : 0; } } /** * 获取cache 所存的文件相对路径 * @param cacheId 缓存id */ protected String getRealFilePath(String cacheId) { StringBuilder sb = new StringBuilder(cacheDir); if (!cacheDir.endsWith(File.separator)) { sb.append(File.separator); } cacheId = cacheId.toLowerCase(); sb.append(DigestUtils.md5DigestAsHex(cacheId.getBytes())); return sb.toString(); } } 4、对接文件和对象转化文件操作类 public class FileOperate { public final static String DEFAULT_ENCODING = "UTF-8"; /** * 获取文件路径对应文件对象 */ public static Object getFileObject(String filePath) throws IOException, ClassNotFoundException { return getFileObject(new File(filePath)); } /** * 读取文件中的对象 */ public static Object getFileObject(File file) throws IOException, ClassNotFoundException { if (!file.exists()) { return null; } try(ObjectInputStream ois=new ObjectInputStream(new FileInputStream(file))){ return ois.readObject(); } } /** * 读取文件路劲对应文件的内容 * @param filePath 文件路径 * @param encoding 编码格式 * @return 文件对象 */ public static String getFileContent(String filePath,String encoding) throws IOException { return getFileContent(new File(filePath), encoding); } /** * 读取文件的文本内容 */ public static String getFileContent(File file,String encoding) throws IOException { if (!file.exists()) { return null; } try (BufferedInputStream bis = new BufferedInputStream(new FileInputStream(file)); ByteArrayOutputStream baos = new ByteArrayOutputStream()) { encoding = StringUtils.isEmpty(encoding) ? DEFAULT_ENCODING : encoding; int readLen; byte[] data = new byte[4096]; while ((readLen = bis.read(data)) != -1) { baos.write(data, 0, readLen); } return baos.toString(encoding); } } /** * 读取文件大小 */ public static long getFileLength(File file) throws IOException { if (!file.exists()) { return 0; } long total = 0; try(FileInputStream fis=new FileInputStream(file)){ while (true) { int expect = fis.available(); if (expect < 0) { break; } skip(fis,expect); total += expect; } } return total; } public static void skip(FileInputStream fis, long expect) throws IOException { int maxTryTime = 16; while (expect > 0 && maxTryTime-- > 0) { long current = fis.skip(expect); if (current == expect) { return; }else { expect -= current; } } } /** * 保存内荣到文件 */ public static boolean saveContentToFile(String filePath, String content) throws IOException { return saveContentToFile(filePath, content, null); } /** * 保存内荣到文件 */ public static boolean saveContentToFile(String filePath, String content,String encoding) throws IOException { if (StringUtils.isEmpty(encoding)) { encoding = DEFAULT_ENCODING; } return saveContentToFile(filePath, content.getBytes(encoding)); } /** * 保存内容到文件 */ public static boolean saveContentToFile(String filePath, byte[] data) throws IOException { if(!FileOperate.createDir(filePath,true)){ return false; } try (FileOutputStream fos = new FileOutputStream(filePath)) { fos.write(data); fos.flush(); return true; } } /** * 保存对象到文件中 */ public static boolean saveObjectToFile(String filePath, Object obj) throws IOException { if(!FileOperate.createDir(filePath,true)){ return false; } try (ObjectOutputStream oos=new ObjectOutputStream(new FileOutputStream(filePath))){ oos.writeObject(obj); oos.flush(); return true; } } /** * 创建目录 */ public static boolean createDir(String path, boolean isFile) { File file = new File(path); if (isFile) { file = file.getParentFile(); } if (!file.exists()) { return file.mkdirs(); }else { return true; } } } 5、缓存对象类 @Data public class FileCacheObject implements Serializable { private static final long serialVersionUID = 908523022948306952L; private long createTime; private long timeout; private Object storageObject; public FileCacheObject() { } public FileCacheObject(Object storageObject) { this(Integer.MAX_VALUE, storageObject); } public FileCacheObject(long timeout, Object storageObject) { if (!(storageObject instanceof Serializable)) { throw new IllegalArgumentException("storage object must implement Serializable"); } this.createTime = System.currentTimeMillis(); this.timeout = timeout; this.storageObject = storageObject; } /** * 缓存是否过期 * @return 缓存存是否过期 */ public boolean isCacheExpire(){ //等于0 表示无过期时间 if (timeout == 0) { return false; } return createTime + timeout < System.currentTimeMillis(); } } 7、测试类 @RunWith(SpringRunner.class) @SpringBootTest public class FileCacheTest { @Resource private FileCache fileCache; private static final String FILE_CACHE_KEY = "file_cache_key"; @Test public void loadData() throws Exception { List<User> users = new ArrayList<>(); User user1 = User.builder().id(1L).accountBalance(1L).email("email1").headPic("pic1").build(); User user12 = User.builder().id(2L).accountBalance(2L).email("email2").headPic("pic2").build(); users.add(user1); users.add(user12); fileCache.set(FILE_CACHE_KEY, users); List userList2= (List<User>)fileCache.get(FILE_CACHE_KEY); System.out.println(userList2); } } 打印的具体结果 ![在这里插入图片描述][20200725155042927.png] 缓存在本地文件 ![在这里插入图片描述][20200725155110637.png] 附上User类: @Data @Builder @NoArgsConstructor @AllArgsConstructor public class User implements Serializable { private Long id; private String username; private String password; private String phone; private String email; private Date created; private Date updated; private String sourceType; private String nickName; private String name; private String status; private String headPic; private String qq; private Long accountBalance; private String isMobileCheck; private String isEmailCheck; private String sex; private Integer userLevel; private Integer points; private Integer experienceValue; private Date birthday; private Date lastLoginTime; } [20200725155042927.png]: /images/20230208/1a8a5a1657464bc6b7129563fe9ad194.png [20200725155110637.png]: /images/20230208/95f6095b57d04e0e9bba2e87c3267549.png
相关 Java类加载机制:从.class文件到对象创建 Java的类加载机制主要包括以下几个步骤: 1. **类搜索**:当程序需要使用一个类时,Java虚拟机会根据类名和当前搜索路径进行搜索。 2. **加载字节码**:找到对 约定不等于承诺〃/ 2024年09月11日 21:06/ 0 赞/ 47 阅读
相关 缓存对象到文件和从文件获取对象 背景 我们在工作中可能会遇到这样的场景,我们需要定时获取获取一个对象。但这个对象比较大,数量比较多。缓存在redis,数据库里面都不太合适。这个时候我们可以考虑将文 冷不防/ 2023年03月01日 12:30/ 0 赞/ 40 阅读
相关 java 对象映射文件_【spring boot】映射properties文件属性--到Java对象 描述 将\.properties中的内容映射到java对象中; 主要步骤 添加 @Component 注解; 使用 @PropertySource 注解指定配置文件位置 小鱼儿/ 2022年11月03日 10:57/ 0 赞/ 274 阅读
相关 从spring获取对象 1. 工具方法 import org.springframework.beans.BeansException; import org.springfra 淩亂°似流年/ 2022年10月20日 13:41/ 0 赞/ 152 阅读
相关 从网络文件系统到对象存储,聊聊对象存储的前世今生 每种技术的产生都有其原因,也有其渊源。网络文件系统的产生有几十年的历史了,但是由于在互联网盛行的当下无法满足某些需求,于是对象存储产生了。今天我们就从 从网络文件系统说起 浅浅的花香味﹌/ 2022年08月28日 05:47/ 0 赞/ 110 阅读
相关 springboot利用缓存存储对象从新获取异常 springboot利用缓存存储对象从新获取异常 将对象存储到内存中后,再取出后就会报java.lang.ClassCastException,原因是 org.sp 落日映苍穹つ/ 2022年06月14日 02:25/ 0 赞/ 162 阅读
相关 文件的打开模式和文件对象方法 文件打开模式 <table style="width:500px;"> <tbody> <tr> <td style="background-color:f 桃扇骨/ 2022年04月15日 00:18/ 0 赞/ 210 阅读
相关 mui---获取入口文件对象 在做APP的时候,发现在Hbuilder里面,如果是已经加载过的页面,可以通过 plus.webview.getWebviewById(id),拿到加载的页面对象,这里的id默 小咪咪/ 2021年12月16日 07:07/ 0 赞/ 318 阅读
相关 获取对应Excel文件的Workbook对象 一 代码 package WorkbookTest; import org.apache.poi.hssf.usermodel.HSSFWorkbo 男娘i/ 2021年07月24日 22:38/ 0 赞/ 434 阅读
还没有评论,来说两句吧...