`
lenj
  • 浏览: 36779 次
  • 性别: Icon_minigender_1
  • 来自: 杭州
最近访客 更多访客>>
社区版块
存档分类
最新评论

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

    博客分类:
  • 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());

  }

  }

  第一次会从文件中读出数据,第二次就会从缓存中读取了,试着多读几次速度明显快很多。
分享到:
评论

相关推荐

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

    服务器启动的时候先把文件中的数据封装成对象数组读入到缓存中,每次访问的时候先判断一下要访问的文件实体有没有被更新,如果没有被更新,就直接从缓存中将想要的数据读出来,当然如果文件被更新了,那只好老老实实...

    JAVA上百实例源码以及开源项目

     数字证书:从文件中读取数字证书,生成文件输入流,输入文件为c:/mycert.cer,获取一个处理X.509证书的证书工厂…… Java+ajax写的登录实例 1个目标文件 内容索引:Java源码,初学实例,ajax,登录  一个Java+ajax写...

    asp.net知识库

    理解DataSet的数据缓存机制 存储过程 可按任意字段排序的分页存储过程(不用临时表的方法,不看全文会后悔) 常用sql存储过程集锦 存储过程中实现类似split功能(charindex) 通过查询系统表得到纵向的表结构 将数据库表...

    python cookbook(第3版)

    6.4 增量式解析大型XML文件 6.5 将字典转换为XML 6.6 解析和修改XML 6.7 利用命名空间解析XML文档 6.8 与关系型数据库的交互 6.9 编码和解码十六进制数 6.10 编码解码Base64数据 6.11 读写二进制数组数据 ...

    JAVA上百实例源码以及开源项目源代码

     数字证书:从文件中读取数字证书,生成文件输入流,输入文件为c:/mycert.cer,获取一个处理X.509证书的证书工厂…… Java+ajax写的登录实例 1个目标文件 内容索引:Java源码,初学实例,ajax,登录  一个Java+ajax写...

    ASP.NET3.5典型模块开发源代码

    20.1.6 用XSL文件转换XML文件 256 20.1.7 删除留言功能 257 20.2 利用数据库技术构造留言板 259 20.2.1 设计保存留言内容的数据库 260 20.2.2 部署数据库提供程序 260 20.2.3 保存数据的方法 261 20.2.4...

    java开源包1

    可以将列表数据缓存到redis中,其他kv结构数据继续缓存到memcached 6. 支持redis的主从集群,可以做读写分离。缓存读取自redis的slave节点,写入到redis的master节点。 Java对象的SQL接口 JoSQL JoSQL...

    java开源包11

    可以将列表数据缓存到redis中,其他kv结构数据继续缓存到memcached 6. 支持redis的主从集群,可以做读写分离。缓存读取自redis的slave节点,写入到redis的master节点。 Java对象的SQL接口 JoSQL JoSQL...

    java开源包2

    可以将列表数据缓存到redis中,其他kv结构数据继续缓存到memcached 6. 支持redis的主从集群,可以做读写分离。缓存读取自redis的slave节点,写入到redis的master节点。 Java对象的SQL接口 JoSQL JoSQL...

    java开源包3

    可以将列表数据缓存到redis中,其他kv结构数据继续缓存到memcached 6. 支持redis的主从集群,可以做读写分离。缓存读取自redis的slave节点,写入到redis的master节点。 Java对象的SQL接口 JoSQL JoSQL...

    java开源包6

    可以将列表数据缓存到redis中,其他kv结构数据继续缓存到memcached 6. 支持redis的主从集群,可以做读写分离。缓存读取自redis的slave节点,写入到redis的master节点。 Java对象的SQL接口 JoSQL JoSQL...

    java开源包5

    可以将列表数据缓存到redis中,其他kv结构数据继续缓存到memcached 6. 支持redis的主从集群,可以做读写分离。缓存读取自redis的slave节点,写入到redis的master节点。 Java对象的SQL接口 JoSQL JoSQL...

    java开源包10

    可以将列表数据缓存到redis中,其他kv结构数据继续缓存到memcached 6. 支持redis的主从集群,可以做读写分离。缓存读取自redis的slave节点,写入到redis的master节点。 Java对象的SQL接口 JoSQL JoSQL...

    java开源包4

    可以将列表数据缓存到redis中,其他kv结构数据继续缓存到memcached 6. 支持redis的主从集群,可以做读写分离。缓存读取自redis的slave节点,写入到redis的master节点。 Java对象的SQL接口 JoSQL JoSQL...

    java开源包8

    可以将列表数据缓存到redis中,其他kv结构数据继续缓存到memcached 6. 支持redis的主从集群,可以做读写分离。缓存读取自redis的slave节点,写入到redis的master节点。 Java对象的SQL接口 JoSQL JoSQL...

    java开源包7

    可以将列表数据缓存到redis中,其他kv结构数据继续缓存到memcached 6. 支持redis的主从集群,可以做读写分离。缓存读取自redis的slave节点,写入到redis的master节点。 Java对象的SQL接口 JoSQL JoSQL...

    java开源包9

    可以将列表数据缓存到redis中,其他kv结构数据继续缓存到memcached 6. 支持redis的主从集群,可以做读写分离。缓存读取自redis的slave节点,写入到redis的master节点。 Java对象的SQL接口 JoSQL JoSQL...

    asp.net技术内幕(1)

    19.1.7 用XML文件进行用户身份验证 19.1.8 用数据库表进行用户身份验证 19.1.9 实现基于角色的身份验证 19.1.10 创建自定义的身份验证票据 19.1.11 表单身份验证和Web阵 19.2 使用Passport...

Global site tag (gtag.js) - Google Analytics