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

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

于是就有了下面这个文件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文件夹操作2

    mkdir("路径文件名"); 创建文件夹 imdir("路径文件名"); 删除文件夹(只能删除空的文件夹) rename("路径",&qu ...

  2. MySQL导入sql脚本中文乱码设置和常用命令

    1. use database_name; 2. set names utf8; (或其他需要的编码) 3. source example.sql (sql文件存放路径) Mysql安装目录数据库目录 ...

  3. 利用openURL,在IOS应用中打开另外一个应用

    在IOS中,实现一个应用启动另外一个应用,使用UIApplication的openURL:方法就可实现,这里以test跳到test02为例.(需要先创建这两个工程) 注册自定义URL协议(在test中 ...

  4. 开源免费的C/C++网络库(c/c++ sockets library)补充

    (1)ACE 庞大.复杂,适合大型项目.开源.免费,不依赖第三方库,支持跨平台. http://www.cs.wustl.edu/~schmidt/ACE.html (2)Asio Asio基于Boo ...

  5. mongodb学习(二)分级查询数组中的值

    (PS: 标题有点不妥当...) 大概是这样...数据结构如下: 需要模糊查询title的值... mongodb中操作语句: 主要是注意这里urlElements不需要加[0]...我开始的时候写成 ...

  6. Bagging和Boosting 概念及区别

    Bagging和Boosting都是将已有的分类或回归算法通过一定方式组合起来,形成一个性能更加强大的分类器,更准确的说这是一种分类算法的组装方法.即将弱分类器组装成强分类器的方法. 首先介绍Boot ...

  7. OC字符串的使用(一)

    #import <Foundation/Foundation.h> int main(int argc, const char * argv[]) { @autoreleasepool { ...

  8. Delphi ShellExecute的用法

    请在interface处uses句中加入ShellAPI 有三个API函数可以运行可执行文件WinExec.ShellExecute和CreateProcess.1.CreateProcess因为使用 ...

  9. delphi下实现控制其它窗体中的控件代码模板(delphi 7安装程序)

    unit Unit1; interface uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms ...

  10. swift 协议传值的实现

    首先呢说下结构 一个ViewController 一个ModelViewController 在ModelViewController中定义了一个协议 这个逻辑 从第一个界面进入第二个界面  从第二个 ...