java文件 缓存读取_java文件读取缓存类

流程图:

 
 

final 外部对象操作时:

通过文件名 -- 在map中找到对应 -- 判断是否修改 --否 -- 返回缓存对象

|

|

调用reload,根据传入的handler进行reload,更新缓存对象,更新操作时间

主要根据的是文件的修改时间,如果本次读取时的修改时间和缓存中的时间相同,则直接返回缓存,否则的话就重新加载文件,更新缓存和时间

重新加载文件的时候需要传入一个 ReloadHandler,以实现更大的灵活性(策略模式),返回一个新的对象并缓存

(待完善:自动清理功能

方案1:FIFO 最简单,但是效率比较低

方案2:访问次数多的留下,少的去掉

方案3:记得大学里编译原理有个更好的方式,忘记了。

)暂时用FIFO

接口:

/**

* 重新加载接口

* @author qihuan

*

*/

public interface ReloadHandler {

/**

* 分析文件

* @return 要缓存的内容

*/

Object processNewCache() throws Exception;

}

缓存类:

/**

*

 
 

* final 外部对象操作时:

* 通过文件名 -- 在map中找到对应 -- 判断是否修改 --否 -- 返回缓存对象

* |

* 是

* |

* 调用reload,根据传入的handler进行reload,更新缓存对象,更新操作时间

*

* @author qihuan

*/

public class FileCache {

/** 缓存map */

private static Map cacheMap = new HashMap();

private static FileCache fileCache;

private static final int MAX_SIZE = 20;

private Queue fileQueue = new LinkedList();

/**

* 单例,多线程一样自信

*

* @return fileCache单例

*/

public static FileCache getInstance(){

if(null == fileCache){

fileCache = new FileCache();

}

return fileCache;

}

/**

* 获取缓存对象

* 获取缓存,如果文件被修改,则重新加载最近配置,内存中超过20个文件缓存,会自动清理

* @param fileName

* @return

* @throws Exception

*/

public Object getCache(String fileName,ReloadHandler handler) throws Exception{

fileName = fileName.trim();

if(isModified(fileName)){

reLoad(fileName,handler);

}

return cacheMap.get(fileName).getCache();

}

/**

* 重新加载

* @param fileName

* @param handler

* @throws Exception

*/

private void reLoad(String fileName, ReloadHandler handler) throws Exception {

CacheElement ele = cacheMap.get(fileName);

if(null == ele){

//文件没有加载过

ele = new CacheElement();

//设置File对象

ele.setFile(new File(fileName));

cacheMap.put(fileName, ele);

//添加新的缓存,记录到队列中

if(!fileQueue.contains(fileName)){

//如果队列中没记录这个,则试图添加并进行清理

cacheClean();

fileQueue.add(fileName);

}

}

//更新缓存

ele.setCache(handler.processNewCache());

//更新修改时间

ele.setLastEditTime(ele.getFile().lastModified());

}

/**

* 判断是否已经修改

*

* @param diXmlName

* @return

*/

private boolean isModified(String fileName) {

CacheElement cacheElement = cacheMap.get(fileName);

if (null == cacheElement) {

//配置文件没有被加载过

return true;

}

if (cacheElement.getFile().lastModified() != cacheElement.getLastEditTime()) {

//被修改

return true;

}

// 没有变化

return false;

}

/**

* FIFO 清理缓存,

*/

private void cacheClean(){

//缓存超过限制之后,进行清理

if(fileQueue.size() >= MAX_SIZE ){

String fileName = fileQueue.poll();

cacheMap.put(fileName, null);

cacheMap.remove(fileName);

}

}

//私有构造

private FileCache(){}

/**

* 缓存元素

*

* @author qihuan

*/

class CacheElement {

public long lastEditTime;

public File file;

public Object cache;

public long getLastEditTime() {

return lastEditTime;

}

public void setLastEditTime(long lastEditTime) {

this.lastEditTime = lastEditTime;

}

//setters and getters...

}

}

缓存一个文件的测试类:

测试类:

/**

* 每2秒去获取一次缓存日期,如果文件更新了,则会返回新的缓存日期

*/

public class CacheTest {

@Test

public void getFileContent() {

int count = 10;

while (count-- > 0) {

try {

getCache();

TimeUnit.SECONDS.sleep(2);

} catch (InterruptedException e) {

e.printStackTrace();

} catch (Exception e) {

e.printStackTrace();

}

}

}

private void getCache() throws Exception {

Date date = (Date)FileCache.getInstance().getCache("e:/1.txt", new ReloadHandler() {

@Override

public Object processNewCache() {

System.out.print("find change ");

return new Date();

}

});

System.out.println(date);

}

}

output:

find change Wed Dec 28 15:25:46 CST 2011 (初始化)

Wed Dec 28 15:25:46 CST 2011

Wed Dec 28 15:25:46 CST 2011

Wed Dec 28 15:25:46 CST 2011

Wed Dec 28 15:25:46 CST 2011

find change Wed Dec 28 15:25:56 CST 2011

Wed Dec 28 15:25:56 CST 2011

Wed Dec 28 15:25:56 CST 2011

Wed Dec 28 15:25:56 CST 2011

Wed Dec 28 15:25:56 CST 2011

实际应用时代码片段

/**

* 获取配置

*

* @param diXmlName

* 接口配置文件名称

* @param diXmlPath

* 接口配置文件完整路径

* @return

* @throws DataConfigException

*/

public DataInterfaceConfig getConfig(final String diXmlName) throws DataConfigException {

DataInterfaceConfig config = null;

final String diXmlPath = Constant.CONFIG_HOME + File.separator + "diConfig" + File.separator + diXmlName;

try {

config = (DataInterfaceConfig) FileCache.getInstance().getCache(diXmlPath, new ReloadHandler() {

@Override

public Object processNewCache() throws Exception {

//重新加载配置文件

return DataInterfaceConfigParser.parser(diXmlPath);

}

});

} catch (Exception e) {

throw new DataConfigException(e);

}

return config;

}

/**

* 从缓存中 根据code 获取 接口配置

* @param code

* @return

* @throws BizException

*/

public DataInterface getDataInterfaceByCode(String code) throws BizException{

Map dataInterface = null;

//获取缓存

try {

dataInterface = (Map) FileCache.getInstance().getCache(Constant.CONFIG_HOME + File.separator + Constant.DIGROUP_CONFIG_XML, new ReloadHandler() {

@Override

public Object processNewCache() throws Exception {

return getAllConfigInGroup();

}

});

} catch (Exception e) {

throw new BizException(e);

}

return dataInterface.get(code);

}

分享到:

18e900b8666ce6f233d25ec02f95ee59.png

72dd548719f0ace4d5f9bca64e1d7715.png

2011-12-29 18:34

浏览 7412

评论

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值