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

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

于是就有了下面这个文件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. doxygen 生成源码文档

    使用doxygen 生成源代码的文档是相当方便的,本文就简单整理下doxygen的使用说明 1. 安装 关于安装的问题不做特殊的说明,这里直接使用命令安装, 源码安装不做介绍 ubuntu: sudo ...

  2. STM8时钟系统详解

    就我个人看来,研究一块单片机,分为新手和老手两种模式,新人迫切的想先用,你得告诉他们怎么样最快的写出一个能跑起来的程序,告诉他们每一个外设的使用方式,老手不同,用的单片机多了外设对于他们而言没太多好奇 ...

  3. java实现——006重建二叉树

    public class T006 { public static void main(String[] args){ int pre[] = {1,2,4,7,3,5,6,8}; int in[] ...

  4. 原生JavaScript之“淘宝轮播图”

    轮播图是我们学习原生js的必经之路 它包含很多基本知识的运用,像this的使用,DOM的操作,还有setInterval的使用和清除,浮动与定位等等,很好的考察了我们的基础知识牢不牢固, 话不多说,直 ...

  5. Selenium2(java)启动常用浏览器 三

    默认启动firefox浏览器 Webdriver driver = new FirefoxDriver(); 启动谷歌浏览器 配置chromedriver WebDriver driver; Syst ...

  6. 理解Twisted与非阻塞编程

    先来看一段代码: # ~*~ Twisted - A Python tale ~*~ from time import sleep # Hello, I'm a developer and I mai ...

  7. js原生写的微博留言板有angularjs效果

    1.HTML: <!DOCTYPE html><html><head lang="en">    <meta charset=" ...

  8. 常见JS挂马方法及如何防止网站被黑客挂马?

    最近有朋友说自己的网站平时并未作弊,文章也都是原创的,更新很稳定.可不知道为什么网站突然就被各大搜索引擎降权了,一直找不到原因.最后发现是网站被挂马了,导致网站被连累了.在此,借助马海祥博客的平台,给 ...

  9. 关于自己封装Web前端框架的思考和探索

    一.引言 首先这些年关于前端技术层出不穷,从最早的只用js做简单验证,到现在发现好像大前端已经无所不能了的感觉.特别是为了降低前端开发复杂度,涌现了一大批 的MVC/MVVM模式的前端框架,不停了刷新 ...

  10. PHP扩展之多线程

    PHP一直以为不支持多线程,后面才知道有基于pThread的扩展包,地址如下: http://php.net/manual/zh/book.pthreads.php 我感兴趣的是以下几个点: 1.Th ...