利用缓存机制快速读取XML文件中的数据

  如果频繁解析文件,速度肯定受到影响,在文件非常大的情况下,甚至是无法忍受的。如果在服务器启动的时候先把文件中的数据封装成对象数组读入到缓存中,每次访问的时候先判断一下要访问的文件实体有没有被更新,如果没有被更新,就直接从缓存中将想要的数据读出来,当然如果文件被更新了,那只好老老实实的解析文件读出想要的数据。管理者对文件的修改次数毕竟是少数,更多的是访问者的访问次数。这样就能很大的提高了访问速度,代价是要占用一定的内存空间,但相比之下应该算小巫吧。

  下面把简单实现的几个Class说一说。

  一 首先实现一个Cache类,里面有读取对象的方法get(),如果文件没有被修改则直接从HashMap里面将对象取出,如果文件被修改则调用readObject()方法实现从文件中读出数据,并同时将读出的数据放入HashMap里,将原来的对象覆盖。这样下次再读数据的时候就可以从缓存中直接读到,并且保证是最新的数据。还有一个判断文件是否被修改的方法getModified();

  代码实现如下:

  import java.io.File;

  import java.util.HashMap;

  public class Cache {

  HashMap mapLastModified = new HashMap();

  HashMap mapValues = new HashMap();

  public Cache() {

  super();

  }

  public Object get(String name, String path, Class clsParser, Class clsInstantiator, Class clsObj) {

  Object obj = null;

  String absPath = getClass().getResource(path).getPath();

  Long modified = getModified(name, absPath);

  if (modified != null) {

  obj = readObject(absPath, clsParser, clsInstantiator, clsObj);

  mapLastModified.put(name, modified);

  mapValues.put(name, obj);

  System.out.println("get object from file");

  } else {

  obj = mapValues.get(name);

  System.out.println("get object from cache");

  }

  return obj;

  }

  private Long getModified(String name, String path) {

  Long modified = new Long(new File(path).lastModified());

  Long saveModified = (Long) mapLastModified.get(name);

  if ((saveModified != null) && (saveModified.longValue() >= modified.longValue())) {

  modified = null;

  }

  return modified;

  }

  private Object readObject(String path, Class clsParser, Class clsInstantiator, Class clsObj) {

  try {

  FileParser parser = (FileParser) clsParser.newInstance();

  Instantiator instantiator = (Instantiator) clsInstantiator.newInstance();

  Object config = parser.parse(path);

  return instantiator.instantiate(clsObj, config);

  } catch (InstantiationException e) {

  e.printStackTrace();

  } catch (IllegalAccessException e) {

  e.printStackTrace();

  }

  return null;

  }

  }

  二 解析XML文件的类XmlFileParser,

  为了方便处理不同文件的解析,在这里先定义一个接口FileParser,XmlFileParser实现了它,如果还有诸如对其他种类文件的解析也可以实现它。

  //FileParser.java

  public interface FileParser {

  Object parse(String path);

  }

  //XmlFileParser.java

  //采用Jdom的解析方式

  import java.io.FileInputStream;

  import java.io.IOException;

  import org.jdom.Document;

  import org.jdom.Element;

  import org.jdom.input.SAXBuilder;

  public class XmlFileParser implements FileParser {

  public XmlFileParser() {

  super();

  }

  public Object parse(String path) {

  FileInputStream fi = null;

  try {

  fi = new FileInputStream(path);

  SAXBuilder sb = new SAXBuilder();

  Document doc = sb.build(fi);

  Element root = doc.getRootElement();

  return root.getChildren();

  } catch (Exception e) {

  e.printStackTrace();

  } finally {

  try {

  fi.close();

  } catch (IOException e1) {

  }

  }

  }

  }

  三 接下来是一个实例化处理的类ListTypeInstantiator,同样为了方便处理不同文件的实例化,在这里先定义一个接口Instantiator,ListTypeInstantiator实现了它。

  //Instantiator.java

  public interface Instantiator {

  Object instantiate(Class clazz, Object configuration);

  }

  //ListTypeInstantiator.java

  import java.util.ArrayList;

  import java.util.List;

  import org.apache.commons.beanutils.BeanUtils;

  import org.jdom.Element;

  public class ListTypeInstantiator implements Instantiator {

  public ListTypeInstantiator() {

  super();

  }

  public Object instantiate(Class clazz, Object configuration) {

  List arr = new ArrayList();

  Object bean = null;

  List children = (List) configuration;

  Element child = null;

  List attributes = null;

  Element attribute = null;

  try {

  for(int i=0; i child = (Element) children.get(i);

  bean = clazz.newInstance();

  attributes = child.getChildren();

  for(int j=0; j attribute = (Element) attributes.get(j);

  BeanUtils.setProperty(bean, attribute.getName(), attribute.getText());

  }

  arr.add(bean);

  }

  } catch(Exception e) {

  e.printStackTrace();

  }

  return arr;

  }

  }

  四 另外还需要一个封装我想要数据形式的JavaBean,这里设为NewsBean{}.

  //NewsBean.java

  public class NewsBean {

  private Long id;

  private String newsTitle;

  private String newsContent;

  private String newsType;

  private String deployDate;

  private String cancelDate;

  public Long getId() {

  return id;

  }

  public void setId(Long id) {

  this.id = id;

  }

  public String getNewsTitle() {

  return newsTitle;

  }

  public void setNewsTitle(String newsTitle) {

  this.newsTitle = newsTitle;

  }

  public String getNewsContent() {

  return newsContent;

  }

  public void setNewsContent(String newsContent) {

  this.newsContent = newsContent;

  }

  public String getNewsType() {

  return newsType;

  }

  public void setNewsType(String newsType) {

  this.newsType = newsType;

  }

  public String getDeployDate() {

  return deployDate;

  }

  public void setDeployDate(String deployDate) {

  this.deployDate = deployDate;

  }

  public String getCancelDate() {

  return cancelDate;

  }

  public void setCancelDate(String cancelDate) {

  this.cancelDate = cancelDate;

  }

  }

  五 最后一步测试结果,将news.xml文件放到classes目录下。

  //MainClass.java

  import java.util.List;

  public class MainClass{

  public static void main(String[] args) throws Exception {

  List news1 = null;

  List news2 = null;

  NewsBean bean = null;

  news1 = (List)Cache.get(

  "news", "/news.xml",

  XmlFileParser.class, ListTypeInstantiator.class, NewsBean.class);

  for (int i = 0; i < news1.size(); i++) {

  bean = (NewsBean) news1.get(i);

  System.out.println(bean.getId());

  System.out.println(bean.getNewsTitle());

  System.out.println(bean.getNewsContent());

  System.out.println(bean.getNewsType());

  System.out.println(bean.getDeployDate());

  System.out.println(bean.getCancelDate());

  }

  news2 = (List)Cache.get(

  "news", "/news.xml",

  XmlFileParser.class, ListTypeInstantiator.class, NewsBean.class);

  for (int i = 0; i < news2.size(); i++) {

  bean = (NewsBean) news2.get(i);

  System.out.println(bean.getId());

  System.out.println(bean.getNewsTitle());

  System.out.println(bean.getNewsContent());

  System.out.println(bean.getNewsType());

  System.out.println(bean.getDeployDate());

  System.out.println(bean.getCancelDate());

  }

  }

  第一次会从文件中读出数据,第二次就会从缓存中读取了,试着多读几次速度明显快很多。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值