您的位置:首页 > 编程语言 > Java开发

java protostuff实现文件级数据缓存,使用文件缓存对象,java文件级数据缓存

2017-10-13 23:08 676 查看
由于业务需要使用文件级别的缓存,特此采用protostuff加上基本的TXT文件操作,来实现基于文件的缓存。

实现以下功能:

文件级别缓存的对象工具类

1、传入一个对象和缓存时间还有缓存名称对这个对象进行缓存

2、传入一个缓存名称查询是否存在这个名称的缓存

3、传入一个缓存名称和该类的类型对象获取对应的缓存

4、传入一个缓存名称删除该名称的缓存

模块一:protostuff序列化使用类

package tool;

import io.protostuff.LinkedBuffer;
import io.protostuff.ProtostuffIOUtil;
import io.protostuff.runtime.RuntimeSchema;

/**
* Created by yy on 2017/9/28.
* 用与序列化以及反序列化对象的类
* 1、传入一个对象,返回该对象序列化后的字节数组
* 2、传入字节数组和类的类型对象,获取这个数据的反序列对象
*/
public class Serialization {
/**
* 传入一个对象,返回这个对象的序列化后的字节数组
* @param object 需要实例化的对象
* @param <T> 传入对象的类型
* @return 返回对应的字节数组
* @throws Exception 序列化失败继续抛出异常
*/
public static <T> byte[] sequence(T object) throws Exception{
//安全判断,要是传入的对象为空返回对应的也是空
if(object==null){
return null;
}
//获取对应的类
Class<T> objectClass = (Class<T>) object.getClass();
//使用LinkedBuffer分配一块默认大小的buffer空间;
LinkedBuffer linkedBuffer = LinkedBuffer.allocate(LinkedBuffer.DEFAULT_BUFFER_SIZE);
try {
//生成对应的图,返回对应的字节数组
//使用ProtoStuff-runtime生成模式,以便在运行时通过反射进行缓存和使用。
RuntimeSchema<T> runtimeSchema = RuntimeSchema.createFrom(objectClass);
return ProtostuffIOUtil.toByteArray(object, runtimeSchema, linkedBuffer);
} catch (Exception e) {
//继续抛出异常
throw new RuntimeException("对象序列化失败!",e);
} finally {
//关闭Buffer空间
linkedBuffer.clear();
}
}

/**
* 根据穿进来的字节数组和具体的类的类型对象,获取对应反序列的结果对象
* @param info 序列化完成的字节数组对象
* @param classInfo 类的类型对象
* @param <T> 具体要转换的类类型
* @return 序列化成功返回序列化前的对象,要是传入的数据为空返回空对象
* @throws Exception 抛出反序列化的异常
*/
public static <T> T reverse(byte[] info,Class<T> classInfo)throws Exception{
//安全判断
if(info.length==0||classInfo==null){
return null;
}
//根据传进来的数据反序列具体对象
try{
RuntimeSchema<T> runtimeSchema = RuntimeSchema.createFrom(classInfo);
T object =runtimeSchema.newMessage();
ProtostuffIOUtil.mergeFrom(info,object,runtimeSchema);
return object;
}catch(Exception e){
throw new RuntimeException("反序列对象失败!",e);
}
}
}


模块二:MD5加密(用于文件名生成)

package tool;

import java.security.MessageDigest;

/**
* md5的生成类
* Created by yy on 2017/10/11.
*/
public class MD5maker {
public static String make(String value){
String md5str = "";
try {
MessageDigest md = MessageDigest.getInstance("MD5");
byte[] input = value.getBytes();
byte[] buff = md.digest(input);
md5str = bytesToHex(buff);
} catch (Exception e) {
e.printStackTrace();
}
return md5str;
}

/**
* 换成16进制
* @param bytes
* @return
*/
private static String bytesToHex(byte[] bytes) {
StringBuffer md5str = new StringBuffer();
int digital;
for (int i = 0; i < bytes.length; i++) {
digital = bytes[i];
if (digital < 0) {
digital += 256;
}
if (digital < 16) {
md5str.append("0");
}
md5str.append(Integer.toHexString(digital));
}
return md5str.toString().toUpperCase();
}
}

模块三:缓存工具类

package tool;

import org.apache.commons.lang3.StringEscapeUtils;

import java.io.*;

/**
* Created by yy on 2017/9/29.
* 文件级别缓存的对象工具类
* 1、传入一个对象和缓存时间还有缓存名称对这个对象进行缓存
* 2、传入一个名称查询是否存在这个名称的缓存
* 3、传入一个名称和该类的类型对象获取对应的缓存
* 4、传入一个缓存名称删除该名称的缓存
*/
public class CacheBF {
/**
* 根据穿进来的名称和实体缓存对象到文件中
* @param name 键名
* @param object 需要保存的实体
* @param time 过期时间秒
* @param <T> 传入的实体类型
* @return 保存成功返回true,失败返回false
*/
public static <T> boolean  cache(String name,T object,int time) throws Exception{

File file=CacheBF.getCacheFile(name);//获取缓存文件
FileWriter fw=new FileWriter(file);
BufferedWriter bw = new BufferedWriter(fw);
//设置过期时间
bw.write((System.currentTimeMillis()+(time*1000))+"");
bw.newLine();
//设置缓存信息
bw.write(StringEscapeUtils.escapeJava(new String(Serialization.sequence(object))));//添加转义
bw.close();
fw.close();
return true;
}

/**
* 根据传进来的文件名,和类的类型获取缓存的实体类
* @param name 缓存名称
* @param objectClass 需要取得的实体类型
* @param <T> 旋回对应实例
* @return
* @throws Exception
*/
public static <T> T get(String name,Class<T> objectClass)throws Exception{

T vo=null;
File file=new File(CacheBF.getCacheFileName(name));//获取缓存文件
if (file.exists()){//判断文件是否存在
FileReader fr=new FileReader(file);
BufferedReader br=new BufferedReader(fr);
Long now =System.currentTimeMillis();
Long time=Long.parseLong(br.readLine());//判断文件缓存是否过期
String object=StringEscapeUtils.unescapeJava(br.readLine());//返回程序,反转义字符
br.close();

d8c2
fr.close();
if (time>now){
vo= Serialization.reverse(object.getBytes(),objectClass);
}else{
file.delete();//过期删除文件,删除前关闭输出流
}
}
return vo;
}

/**
* 传入一个缓存名称,查询是否存在此缓存
* @param name 缓存名称
* @return 存在并且不过期返回true,否则返回false
* @throws Exception
*/
public static boolean check(String name)throws Exception{

boolean back=false;
File file=new File(CacheBF.getCacheFileName(name));//获取缓存文件
if (file.exists()){
FileReader fr=new FileReader(file);
BufferedReader br=new BufferedReader(fr);
Long now=System.currentTimeMillis();
Long time=Long.parseLong(br.readLine());//判断文件缓存是否过期
br.close();
fr.close();
if (time>now){
back=true;
}else{
file.delete();//过期删除文件
}
}
return back;
}

/**
* 删除穿进来的缓存名称的文件
* @param name 需要删除的缓存的名称
* @throws Exception
*/
public static void delete(String name)throws Exception{

File file=new File(CacheBF.getCacheFileName(name));
if (file.exists()){
file.delete();
}

}
/**
* 根据缓存的名称获取需要操作的文件对象
* 1、判断父类目录cache是否存在,不存在则创建
* 2、判断当前文件是否存在,存在删除后创建,不存在直接创建
* 3、文件名MD5加密
* @param name 需要得到的缓存的名称
* @return
* @throws Exception
*/
private static File getCacheFile(String name)throws Exception{

File file=new File(CacheBF.getCacheFileName(name));//获取操作对象
//判断父目录是否存在
if (!file.getParentFile().exists()){
file.getParentFile().mkdir();
}
//判断当前文件是否存在
if (!file.exists()){
file.createNewFile();
}else {
file.delete();
file.createNewFile();
}
return file;
}

/**
* 传入缓存名获取缓存的文件名
* @param name 缓存名
* @return
*/
private static String getCacheFileName(String name){
name=MD5maker.make(name)+".txt";//获取文件名
StringBuffer fileName=new StringBuffer(System.getProperty("user.dir"))
.append(File.separator).append("src")
.append(File.separator).append("main")
.append(File.separator).append("webapp")
.append(File.separator).append("WEB-INF")
.append(File.separator).append("cache")
.append(File.separator).append(name);//获取文件路径
return fileName.toString();
}
}


模块四:测试

import tool.CacheBF;
import tool.Serialization;

import java.io.File;

/**
* Created by yy on 2017/10/11.
* 文件缓存测试
*/
public class test {
public static void main(String args[]) {
Data data= new Data();
data.setInfo("hello");
data.setName("world");
try {
CacheBF.cache("123",data,100);

System.out.println("缓存是否存在:"+CacheBF.check("123"));
Data da=CacheBF.get("123",Data.class);
System.out.println(da);

CacheBF.delete("123");
System.out.println("缓存是否存在:"+CacheBF.check("123"));
Data dd=CacheBF.get("123",Data.class);
System.out.println(dd);
}catch (Exception e){
e.printStackTrace();
}

}
}
//测试使用
class Data{
private String name;
private String info;

public String getName() {
return name;
}

public void setName(String name) {
this.name = name;
}

public String getInfo() {
return info;
}

public void setInfo(String info) {
this.info = info;
}

@Override
public String toString() {
return "Data{" +
"name='" + name + '\'' +
", info='" + info + '\'' +
'}';
}
}
模块五:测试输出

缓存是否存在:true
Data{name='world', info='hello'}
缓存是否存在:false
null

模块六:文件内容(A8AE104615CB4E966DDB435F3E575A02.txt)

1508081000098
\n\u0005world\u0012\u0005hello
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
相关文章推荐