工作中经常需要处理对象的处理,有的时候还需要将对象保存到文件中做持久化。

特别是当不能使用数据库的时候就特别需要一个简单的对象集合的增删改查操作,

于是就有了下面这个文件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基于文件的对象存储的更多相关文章

  1. 基于openshift+华为对象存储的CSI开发

    目录 需求来源 环境准备 代码修改 镜像下载 镜像生成 修改部署文件 部署CSI插件 CSI原理 核心原理 生命周期: 组件介绍 FAQ 参考: 需求来源 项目上目前使用的是openshift 3.1 ...

  2. java常量池与对象存储

    一 数据存储位置                                 我们先来谈谈数据的存储位置,有五个地方可以存储数据 (1)寄存器:这是最快的存储区,因为它位于不同于其他存储区的地方- ...

  3. 基于七牛云对象存储,搭建一个自己专属的极简Web图床应用(手摸手的注释讲解核心部分的实现原理)

    一个极简的Web图床应用,支持复制粘贴与拖拽上传图片 1.开发缘由 日常使用Vs Code编写markdown笔记与博客文章时,在文章中插入图片时发现非常不便 使用本地文件编写相对路径---没法直接复 ...

  4. java操作文件流对象

    所有流对象 InputStream 字节流         FileInputStream 字节流 专门读写非文本文件的         BufferedInputStream 高效流 OutPutS ...

  5. 【分布式技术专题】「OSS中间件系列」Minio的文件服务的存储模型及整合Java客户端访问的实战指南

    Minio的元数据 数据存储 MinIO对象存储系统没有元数据数据库,所有的操作都是对象级别的粒度的,这种做法的优势是: 个别对象的失效,不会溢出为更大级别的系统失效. 便于实现"强一致性& ...

  6. 【Linux】【Basis】块存储,文件存储,对象存储

    1. 块存储: 定义:这种接口通常以QEMU Driver或者Kernel Module的方式存在,这种接口需要实现Linux的Block Device的接口或者QEMU提供的Block Driver ...

  7. 【巨杉数据库Sequoiadb】巨杉⼯具系列之一 | ⼤对象存储⼯具sdblobtool

    近期,巨杉数据库正式推出了完整的SequoiaDB 工具包,作为辅助工具,更好地帮助大家使用和运维管理分布式数据库.为此,巨杉技术社区还将持续推出工具系列文章,帮助大家了解巨杉数据库丰富的工具矩阵. ...

  8. Github 29K Star的开源对象存储方案——Minio入门宝典

    对象存储不是什么新技术了,但是从来都没有被替代掉.为什么?在这个大数据发展迅速地时代,数据已经不单单是简单的文本数据了,每天有大量的图片,视频数据产生,在短视频火爆的今天,这个数量还在增加.有数据表明 ...

  9. swift对象存储

    swift对象存储 简介 OpenStack Object Storage(Swift)是OpenStack开源云计算项目的子项目之一,被称为对象存储,提供了强大的扩展性.冗余和持久性.对象存储,用于 ...

随机推荐

  1. php字符串压缩

    在PHP中偶尔遇到字符串的压缩,比如一个长字符串,数据库开始设计的字段存不下,但是又不想改数据库字段存储长度,就可以用压缩的方式降低数据字段字符串的长度数量级,把几百个字符的字符串压缩到几十个字符.总 ...

  2. 【转】每一个程序员需要了解的10个Linux命令

    作为一个程序员,在软件开发职业生涯中或多或少会用到Linux系统,并且可能会使用Linux命令来检索需要的信息.本文将为各位开发者分享10个有用的Linux命令,希望对你会有所帮助. 以下就是今天我们 ...

  3. 设置MyEclipse黑色主题背景

    设置MyEclipse黑色主题背景 1. 下载 http://eclipsecolorthemes.org/  看哪个合适直接点击进入, 下载右边的epf 2. 下载完成...打开myeclipse. ...

  4. ARM处理器工作模式

    学习ARM处理器参考的首选资料是ARM Architecture Reference Manual,是最专业权威的学习资料. ARM处理器共有7种工作模式,如表1-1和1-2所示: 表1-1 处理器工 ...

  5. 【转】安卓布局:layout_weight的理解

    android:layout_weight详细分析介绍: 布局文件是:<?xml version="1.0" encoding="utf-8"?>& ...

  6. 2)Javascript设计模式:Singleton模式

    Singleton模式 var User = (function() { var instance; function _User(){} _User.prototype.say = function ...

  7. easyui 翻译

    1,DataGrid checkOnSelect: 设置成true:用户点击一行的时候,复选框被选中或者是取消选中 设置成false:只有当用户点击复选框的时候,复选框才能被选中或者是取消选中 sel ...

  8. Oracle数据库中的函数

    1.随机数函数:DBMS_RANDOM.RANDOM )) FROM DUAL; --产生一个100以内的随机数 *dbms_random.value) FROM dual; --产生一个100-10 ...

  9. Mysql 创建数据库后修改属性

    添加表字段 alter table table1 add transactor varchar(10) not Null; alter table   table1 add id int unsign ...

  10. DevExpress控件学习总结2(转)

    1.TextEditor(barEditItem)取文本string editValue = barEditItem1.EditValue.ToString(); //错误,返回null string ...