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

简介:
接到一个任务,让我做一个公司网站的后台管理系统。要求很简单,就一个新闻发布模块和一个招聘信息发布模块。但不能用DB,只能用文件存取的形式实现。

不用考虑肯定是用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<children.size(); i++) {
child = (Element) children.get(i);
bean = clazz.newInstance();
attributes = child.getChildren();
for(int j=0; j<attributes.size(); 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());
}
}

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

本文转自kenty博客园博客,原文链接http://www.cnblogs.com/kentyshang/archive/2007/01/24/628588.html如需转载请自行联系原作者


kenty

相关文章
|
3月前
|
Web App开发 存储 缓存
如何精准清除特定类型或标签的缓存数据?
如何精准清除特定类型或标签的缓存数据?
362 57
|
5月前
|
缓存 NoSQL 关系型数据库
美团面试:MySQL有1000w数据,redis只存20w的数据,如何做 缓存 设计?
美团面试:MySQL有1000w数据,redis只存20w的数据,如何做 缓存 设计?
美团面试:MySQL有1000w数据,redis只存20w的数据,如何做 缓存 设计?
|
11天前
|
XML 数据采集 API
用Lxml高效解析XML格式数据:以天气API为例
免费Python教程:实战解析中国天气网XML数据,详解Lxml库高效解析技巧、XPath用法、流式处理大文件及IP封禁应对策略,助你构建稳定数据采集系统。
99 0
|
2月前
|
存储 缓存 监控
一次缓存引发的文件系统数据不一致问题排查与深度解析
本文详述了一次由自研分布式文件系统客户端 EFC 的缓存架构更新所引发的严重数据不一致问题的完整排查过程。
一次缓存引发的文件系统数据不一致问题排查与深度解析
|
6月前
|
缓存 并行计算 PyTorch
PyTorch CUDA内存管理优化:深度理解GPU资源分配与缓存机制
本文深入探讨了PyTorch中GPU内存管理的核心机制,特别是CUDA缓存分配器的作用与优化策略。文章分析了常见的“CUDA out of memory”问题及其成因,并通过实际案例(如Llama 1B模型训练)展示了内存分配模式。PyTorch的缓存分配器通过内存池化、延迟释放和碎片化优化等技术,显著提升了内存使用效率,减少了系统调用开销。此外,文章还介绍了高级优化方法,包括混合精度训练、梯度检查点技术及自定义内存分配器配置。这些策略有助于开发者在有限硬件资源下实现更高性能的深度学习模型训练与推理。
1161 0
|
5月前
|
Android开发 开发者
Android自定义View之不得不知道的文件attrs.xml(自定义属性)
本文详细介绍了如何通过自定义 `attrs.xml` 文件实现 Android 自定义 View 的属性配置。以一个包含 TextView 和 ImageView 的 DemoView 为例,讲解了如何使用自定义属性动态改变文字内容和控制图片显示隐藏。同时,通过设置布尔值和点击事件,实现了图片状态的切换功能。代码中展示了如何在构造函数中解析自定义属性,并通过方法 `setSetting0n` 和 `setbackeguang` 实现功能逻辑的优化与封装。此示例帮助开发者更好地理解自定义 View 的开发流程与 attrs.xml 的实际应用。
120 2
Android自定义View之不得不知道的文件attrs.xml(自定义属性)
|
5月前
|
消息中间件 缓存 NoSQL
基于Spring Data Redis与RabbitMQ实现字符串缓存和计数功能(数据同步)
总的来说,借助Spring Data Redis和RabbitMQ,我们可以轻松实现字符串缓存和计数的功能。而关键的部分不过是一些"厨房的套路",一旦你掌握了这些套路,那么你就像厨师一样可以准备出一道道饕餮美食了。通过这种方式促进数据处理效率无疑将大大提高我们的生产力。
217 32
|
4月前
|
XML 存储 数据格式
抖音卡片链接生成器,xml卡片数据支持快手,通过XPOSED实现制作
本项目介绍抖音/快手卡片链接生成技术,包含技术原理与核心功能实现。通过Xposed框架Hook目标APP关键方法,自定义卡片生成与跳转逻辑。卡片数据以XML格式存储,便于解析和跨平台使用。提供完整代码示例,涵盖Xposed模块配置、XML数据结构、Hook实现及卡片生成器核心类。下载地址:https://www.pan38.com/share.php?code=DuNzA,提取码:8888(仅供学习参考)。
|
4月前
|
存储 缓存
.NET 6中Startup.cs文件注入本地缓存策略与服务生命周期管理实践:AddTransient, AddScoped, AddSingleton。
记住,选择正确的服务生命周期并妥善管理它们是至关重要的,因为它们直接影响你的应用程序的性能和行为。就像一个成功的建筑工地,工具箱如果整理得当,工具选择和使用得当,工地的整体效率将会大大提高。
174 0
|
7月前
|
机器学习/深度学习 人工智能 缓存
MHA2MLA:0.3%数据微调!复旦团队开源推理加速神器,KV缓存狂降96.87%
MHA2MLA是复旦大学、华东师范大学、上海AI Lab等机构联合推出的数据高效微调方法,通过引入多头潜在注意力机制(MLA),显著优化基于Transformer的LLM推理效率,降低推理成本。
246 1
MHA2MLA:0.3%数据微调!复旦团队开源推理加速神器,KV缓存狂降96.87%

相关课程

更多