Java基于文件的对象存储
工作中经常需要处理对象的处理,有的时候还需要将对象保存到文件中做持久化。
特别是当不能使用数据库的时候就特别需要一个简单的对象集合的增删改查操作,
于是就有了下面这个文件DB的工具类
package com.cc.fileDb; import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.EOFException;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; /**单例模式的文件数据库工具类*/
public class FileDb {
private static final Logger log = LoggerFactory.getLogger(FileDb.class);
private static FileDb single=null;
private static Map<String,List<HashMap<String,String>>> cashs = new HashMap<String,List<HashMap<String,String>>>();
private String baseDir ;
private FileDb(String baseDir){
this.baseDir = baseDir;
File f = new File(baseDir);
if (!f.exists()) {
f.mkdirs();
}
}
/*初始化文件数据库的工作目录*/
public static synchronized FileDb getInstance(String baseDir) {
if (single == null) {
single = new FileDb(baseDir);
}
return single;
}
/*将文件对象初始化到内存*/
public synchronized List<HashMap<String,String>> getDataList(String dbName) throws Exception{
List<HashMap<String,String>> res = new ArrayList<HashMap<String,String>>();
if(single == null) throw new Exception("init db first!");
if(cashs.containsKey(dbName))return cashs.get(dbName);
ObjectInputStream in = null;
File f = new File(baseDir+dbName);
try{
if(!f.exists())f.createNewFile();
in = new ObjectInputStream(new FileInputStream(baseDir+dbName));
while(f.length()>0){
Object o = in.readObject();
if(!(o instanceof HashMap))continue;
HashMap<String, String> map = (HashMap<String,String>) o;
res.add(map);
}
}catch(EOFException ex){
}catch(Exception e){
e.printStackTrace();
log.error(e.getLocalizedMessage());
}finally{
try {
cashs.put(dbName, res);
if(in!=null)in.close();
} catch (IOException e) {
log.error(e.getLocalizedMessage());
}
}
return res;
}
/*添加map对象到数据库*/
public synchronized boolean add(String dbName,HashMap<String,String> data) throws Exception{
if(!cashs.containsKey(dbName))cashs.put(dbName, getDataList(dbName));
cashs.get(dbName).add(data);
return true;
}
/*根据条件查找符合的第一个map对象*/
public synchronized HashMap<String,String> getFirst(String dbName,HashMap<String,String> param) throws Exception{
if(!cashs.containsKey(dbName))cashs.put(dbName, getDataList(dbName));
if(cashs.get(dbName).size()==0)return null;
boolean fit = true;
for(HashMap<String,String> item : cashs.get(dbName)){
for(String key : param.keySet()){
if(!param.get(key).equals(item.get(key))){
fit = false;
break;
}
}
if(fit)return item;
fit= true;
}
return null;
}
/*根据条件获得全部符合的map对象*/
public synchronized List<HashMap<String,String>> getFits(String dbName,HashMap<String,String> param) throws Exception{
if(!cashs.containsKey(dbName))cashs.put(dbName, getDataList(dbName));
if(cashs.get(dbName).size()==0)return null;
List<HashMap<String,String>> ls = new ArrayList<HashMap<String,String>>();
boolean fit = true;
for(HashMap<String,String> item : cashs.get(dbName)){
if(param!=null&& !param.keySet().isEmpty())for(String key : param.keySet()){
if(!param.get(key).equals(item.get(key))){
fit = false;
break;
}
}
if(fit)ls.add(item);
fit = true;
}
return ls;
}
/*update更新或保存对象*/
public synchronized boolean save(String dbName,HashMap<String,String> param,HashMap<String,String> data) throws Exception{
if(!cashs.containsKey(dbName))cashs.put(dbName, getDataList(dbName));
if(cashs.get(dbName).size()==0){
cashs.get(dbName).add(data);
}else{
boolean fit = true;
for(HashMap<String,String> item : cashs.get(dbName)){
if(param!=null&& !param.keySet().isEmpty())
for(String key : param.keySet()){
if(!param.get(key).equals(item.get(key))){
fit = false;
break;
}
}
if(fit){
if(data!=null&& !data.keySet().isEmpty())
for(String key : data.keySet()){
item.put(key, data.get(key));
}
}
fit = true;
}
}
return true;
}
/*根据条件删除map信息*/
public synchronized boolean delete(String dbName,HashMap<String,String> param) throws Exception{
if(!cashs.containsKey(dbName))cashs.put(dbName, getDataList(dbName));
if(cashs.get(dbName).size()==0){
return false;
}else{
boolean fit = true;
List<Integer> dels = new ArrayList<Integer>();
int i = 0;
for(HashMap<String,String> item : cashs.get(dbName)){
if(param!=null&& !param.keySet().isEmpty())
for(String key : param.keySet()){
if(!param.get(key).equals(item.get(key))){
fit = false;
break;
}
}
if(fit){
dels.add(i);
}
fit = true;
i++;
}
Iterator<Integer> mm = dels.iterator();
int j = 0;
while(mm.hasNext()){
int k = mm.next() ;
k -= j;
cashs.get(dbName).remove(k);
j++;
}
}
return true;
}
/*将map数组信息刷入到文件中*/
public synchronized boolean commit(String dbName) throws Exception{
if(!cashs.containsKey(dbName))return false;
File file = new File(baseDir+dbName);
ObjectOutputStream out = null;
log.info("commit"+dbName+".size="+cashs.get(dbName).size());
if(cashs.get(dbName)!=null&&cashs.get(dbName).size()>0){
FileOutputStream fos = new FileOutputStream(file, false);
out = new ObjectOutputStream(fos);
for(HashMap<String,String> o: cashs.get(dbName)){
out.writeObject(o);
}
fos.close();
if(out!=null)out.close();
}else{
log.info("commit["+baseDir+dbName+"].size="+cashs.get(dbName).size()+file.delete());
}
return true;
}
/*清空内存中的文件数据库对象*/
public synchronized boolean clear(String dbName) throws Exception{
if(!cashs.containsKey(dbName)){
log.info("uninit "+dbName);
return false;
}
cashs.put(dbName, new ArrayList<HashMap<String,String>>());
return true;
} }
class MyObjectOutputStream extends ObjectOutputStream{
public MyObjectOutputStream() throws IOException {
super();
}
public MyObjectOutputStream(OutputStream out) throws IOException {
super(out);
}
@Override
protected void writeStreamHeader() throws IOException {
return;
} /**
* 对象转数组
* @param obj
* @return
*/
public static byte[] toByteArray (Object obj) {
byte[] bytes = null;
ByteArrayOutputStream bos = new ByteArrayOutputStream();
try {
ObjectOutputStream oos = new ObjectOutputStream(bos);
oos.writeObject(obj);
oos.flush();
bytes = bos.toByteArray ();
oos.close();
bos.close();
} catch (IOException ex) {
ex.printStackTrace();
}
return bytes;
} /**
* 数组转对象
* @param bytes
* @return
*/
public static Object toObject (byte[] bytes) {
Object obj = null;
try {
ByteArrayInputStream bis = new ByteArrayInputStream (bytes);
ObjectInputStream ois = new ObjectInputStream (bis);
obj = ois.readObject();
ois.close();
bis.close();
} catch (IOException ex) {
ex.printStackTrace();
} catch (ClassNotFoundException ex) {
ex.printStackTrace();
}
return obj;
}
}
实现了简单的文件的操作和对象处理的增删改查,下面是测试用例
package com.cc.fileDb; import java.util.HashMap;
import java.util.List; /**
* Hello world!
*
*/
public class App
{
public static void main( String[] args )
{
FileDb fd = FileDb.getInstance("D:\\"); try {
// for(HashMap<String,String> map : fd.getDataList("test.db")){
// System.out.println(map.get("index")+"==>"+map.get("name"));
// }
// fd.getDataList("test.db");//初始化数据
// fd.clear("test.db");//清空数据
for(int i =0;i<10;i++){
HashMap<String, String> data = new HashMap<String, String>() ;
data.put("name", "AA:"+System.currentTimeMillis());
data.put("index", "I:"+i);
fd.add("test.db", data );
} fd.commit("test.db");//将数据刷入文件
Thread.sleep(1000);
// for(HashMap<String,String> map : fd.getDataList("test.db")){
// System.out.println(map.get("index")+"==>"+map.get("name"));
// }
HashMap<String, String> param = new HashMap<String, String>() ;
param.put("index", "I:"+4);
//修改内容
HashMap<String, String> data = new HashMap<String, String>();
data.put("index", "I:"+4);
data.put("name", "hello world!");
data.put("ext", "201702091111");
fd.save("test.db", param, data);
//查找内容
HashMap<String, String> map0 = fd.getFirst("test.db", param );
System.out.println(map0 .get("index")+"==>"+map0.get("name"));
param.put("index", "I:"+5);
//删除内容
fd.delete("test.db", param);
for(HashMap<String,String> map : fd.getDataList("test.db")){
System.out.println(map.get("index")+"==>"+map.get("name"));
} param.put("index", "I:"+6);
//获取全部符合的内容
List<HashMap<String, String>> maps = fd.getFits("test.db", param );
for(HashMap<String, String> map : maps)
System.out.println(map.get("name") );
fd.commit("test.db");
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
好了,以后就可以将文件作为map集合数据的存储操作了,同事只要对上述代码中的带修改为你自己的可序列化对象就可以实现你自己对象的文件数据库了,做增删改查也十分方便。
虽然实现了简单的线程安全处理,不过还没有做过线程安全的测试,如果在用的过程中有遇到任何问题,欢迎联系我!
Java基于文件的对象存储的更多相关文章
- 基于openshift+华为对象存储的CSI开发
目录 需求来源 环境准备 代码修改 镜像下载 镜像生成 修改部署文件 部署CSI插件 CSI原理 核心原理 生命周期: 组件介绍 FAQ 参考: 需求来源 项目上目前使用的是openshift 3.1 ...
- java常量池与对象存储
一 数据存储位置 我们先来谈谈数据的存储位置,有五个地方可以存储数据 (1)寄存器:这是最快的存储区,因为它位于不同于其他存储区的地方- ...
- 基于七牛云对象存储,搭建一个自己专属的极简Web图床应用(手摸手的注释讲解核心部分的实现原理)
一个极简的Web图床应用,支持复制粘贴与拖拽上传图片 1.开发缘由 日常使用Vs Code编写markdown笔记与博客文章时,在文章中插入图片时发现非常不便 使用本地文件编写相对路径---没法直接复 ...
- java操作文件流对象
所有流对象 InputStream 字节流 FileInputStream 字节流 专门读写非文本文件的 BufferedInputStream 高效流 OutPutS ...
- 【分布式技术专题】「OSS中间件系列」Minio的文件服务的存储模型及整合Java客户端访问的实战指南
Minio的元数据 数据存储 MinIO对象存储系统没有元数据数据库,所有的操作都是对象级别的粒度的,这种做法的优势是: 个别对象的失效,不会溢出为更大级别的系统失效. 便于实现"强一致性& ...
- 【Linux】【Basis】块存储,文件存储,对象存储
1. 块存储: 定义:这种接口通常以QEMU Driver或者Kernel Module的方式存在,这种接口需要实现Linux的Block Device的接口或者QEMU提供的Block Driver ...
- 【巨杉数据库Sequoiadb】巨杉⼯具系列之一 | ⼤对象存储⼯具sdblobtool
近期,巨杉数据库正式推出了完整的SequoiaDB 工具包,作为辅助工具,更好地帮助大家使用和运维管理分布式数据库.为此,巨杉技术社区还将持续推出工具系列文章,帮助大家了解巨杉数据库丰富的工具矩阵. ...
- Github 29K Star的开源对象存储方案——Minio入门宝典
对象存储不是什么新技术了,但是从来都没有被替代掉.为什么?在这个大数据发展迅速地时代,数据已经不单单是简单的文本数据了,每天有大量的图片,视频数据产生,在短视频火爆的今天,这个数量还在增加.有数据表明 ...
- swift对象存储
swift对象存储 简介 OpenStack Object Storage(Swift)是OpenStack开源云计算项目的子项目之一,被称为对象存储,提供了强大的扩展性.冗余和持久性.对象存储,用于 ...
随机推荐
- 《算法导论》归并排序----merge-sort
伪代码请见<算法导论>2.3节 merge-sort实现: public class MergeSort { public static void sort(double [ ...
- linux下实现ftp匿名用户的上传和下载文件功能
1.配置/etc//vsftpd/vsftpd.conf 文件如下: 打开文件,改变如下选项,如果文件中没有该选项,需要自己手动编写该选项 write_enable=YES anonymous_ena ...
- 从字符串拼接看JS优化原则
来自知乎的问题:JavaScript 怎样高效拼接字符串? 请把以下用于连接字符串的JavaScript代码修改为更高效的方式: var htmlString ='< div class=”co ...
- EF dbcontext上下文的处理
,那么我们整个项目里面上下文的实例会有很多个,我们又遇到了多次,当我们在编程的时候遇到多的时候,一般我们就要想想能不能解决多这个问题. (2)这里我要说的是EF上下文怎么管理呢?很简单啦,就是要保证线 ...
- 安卓 SQLite error:SQLite database locked exception while compling : PRAGMA journal_mode .....
项目中频繁的切换Tab键,会频繁地从数据库读取数据,这是报出这样的错误: 解决方法是在国外的某论坛找到的 : 在插入数据的时候,首先: SQLiteDatabase db = SQLiteDataba ...
- django学习——基础
在ubuntu下, 安装: pip install django / sudo apt-get install python-django 项目与应用 一个project包含多个app,每个app处理 ...
- 前端开发 Grunt 之 Connect详解
在前端开发过程中,我们需要在开发过程中,将开发中的站点部署到服务器上,然后,在浏览器中查看实际的效果,在 Grunt 环境下,可以直接使用集成在 Grunt 中的 Connect 插件完成站点服务器的 ...
- TortoiseSVN使用简介(收藏)
TortoiseSVN使用简介 1.安装及下载client 端 2.什么是SVN(Subversion)? 3.为甚么要用SVN? 4.怎么样在Windows下面建立SVN Repository? 5 ...
- 5分钟了解MySQL5.7的Online DDL雷区
原创作品,允许转载,转载时请务必以超链接形式标明文章 原始出处 .作者信息和本声明.否则将追究法律责任.http://suifu.blog.51cto.com/9167728/1855872 Part ...
- 【angularjs】【学习心得】ng-class总结
原文:http://www.imooc.com/wenda/detail/236998 今天来说一点angularjs中看起来很简单但是实践起来又有不少问题的ng-class吧 ----------- ...