<rt id="bn8ez"></rt>
<label id="bn8ez"></label>

  • <span id="bn8ez"></span>

    <label id="bn8ez"><meter id="bn8ez"></meter></label>

    飛艷小屋

    程序--人生--哲學(xué)___________________歡迎艷兒的加入

    BlogJava 首頁 新隨筆 聯(lián)系 聚合 管理
      52 Posts :: 175 Stories :: 107 Comments :: 0 Trackbacks
    利用緩存機(jī)制快速讀取XML文件中的數(shù)據(jù)

           接到一個(gè)任務(wù),讓我做一個(gè)公司網(wǎng)站的后臺(tái)管理系統(tǒng)。要求很簡(jiǎn)單,就一個(gè)新聞發(fā)布模塊和一個(gè)招聘信息發(fā)布模塊。但不能用DB,只能用文件存取的形式實(shí)現(xiàn)。

           不用考慮肯定是用XML文件進(jìn)行數(shù)據(jù)的存取了,以前做畢設(shè)的時(shí)候也曾經(jīng)實(shí)現(xiàn)過類似的功能,所以關(guān)于XML的讀取并沒有問題。關(guān)鍵是如果考慮到性能的問題就值得推敲一下了,我是新人,以前也沒做過什么設(shè)計(jì),所以做出的東西在一些人眼中可能會(huì)有些稚嫩,那也沒關(guān)系,走自己的路讓別人去說吧:)

           如果頻繁解析文件,速度肯定受到影響,在文件非常大的情況下,甚至是無法忍受的。如果在服務(wù)器啟動(dòng)的時(shí)候先把文件中的數(shù)據(jù)封裝成對(duì)象數(shù)組讀入到緩存中,每次訪問的時(shí)候先判斷一下要訪問的文件實(shí)體有沒有被更新,如果沒有被更新,就直接從緩存中將想要的數(shù)據(jù)讀出來,當(dāng)然如果文件被更新了,那只好老老實(shí)實(shí)的解析文件讀出想要的數(shù)據(jù)。管理者對(duì)文件的修改次數(shù)畢竟是少數(shù),更多的是訪問者的訪問次數(shù)。這樣就能很大的提高了訪問速度,代價(jià)是要占用一定的內(nèi)存空間,但相比之下應(yīng)該算小巫吧。

            下面把簡(jiǎn)單實(shí)現(xiàn)的幾個(gè)Class說一說。

            一 首先實(shí)現(xiàn)一個(gè)Cache類,里面有讀取對(duì)象的方法get(),如果文件沒有被修改則直接從HashMap里面將對(duì)象取出,如果文件被修改則調(diào)用readObject()方法實(shí)現(xiàn)從文件中讀出數(shù)據(jù),并同時(shí)將讀出的數(shù)據(jù)放入HashMap里,將原來的對(duì)象覆蓋。這樣下次再讀數(shù)據(jù)的時(shí)候就可以從緩存中直接讀到,并且保證是最新的數(shù)據(jù)。還有一個(gè)判斷文件是否被修改的方法getModified();
    代碼實(shí)現(xiàn)如下:

    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,
    為了方便處理不同文件的解析,在這里先定義一個(gè)接口FileParser,XmlFileParser實(shí)現(xiàn)了它,如果還有諸如對(duì)其他種類文件的解析也可以實(shí)現(xiàn)它。
    //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) {
       }
      } 
     }
    }

    三 接下來是一個(gè)實(shí)例化處理的類ListTypeInstantiator,同樣為了方便處理不同文件的實(shí)例化,在這里先定義一個(gè)接口Instantiator,ListTypeInstantiator實(shí)現(xiàn)了它。
    //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;
     }
    }

    四 另外還需要一個(gè)封裝我想要數(shù)據(jù)形式的JavaBean,這里設(shè)為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;
     }
    }

    五 最后一步測(cè)試結(jié)果,將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());
      }
    }
    第一次會(huì)從文件中讀出數(shù)據(jù),第二次就會(huì)從緩存中讀取了,試著多讀幾次速度明顯快很多。
     

    posted on 2005-12-03 15:03 天外飛仙 閱讀(178) 評(píng)論(0)  編輯  收藏

    只有注冊(cè)用戶登錄后才能發(fā)表評(píng)論。


    網(wǎng)站導(dǎo)航:
     
    主站蜘蛛池模板: 国产四虎免费精品视频| 亚洲 自拍 另类小说综合图区 | 国产∨亚洲V天堂无码久久久| 国产精品99精品久久免费| 亚洲一级免费视频| 亚洲色婷婷综合开心网| 中文字幕免费在线| 国产天堂亚洲精品| 亚洲邪恶天堂影院在线观看| 国产麻豆免费观看91| 免费无码又爽又刺激网站直播| 成人亚洲国产va天堂| 亚洲gv白嫩小受在线观看| 免费黄色小视频网站| 久久久国产精品无码免费专区| 亚洲变态另类一区二区三区| 亚洲AV综合色区无码一区| 国产又大又粗又硬又长免费| 182tv免费观看在线视频| 四虎成人精品国产永久免费无码 | 黄色毛片视频免费| 亚洲综合色丁香麻豆| 亚洲精品成人在线| 青青视频观看免费99| 日本三级在线观看免费| 美女黄频a美女大全免费皮| 亚洲天堂一区二区三区四区| 亚洲日本一区二区一本一道 | 水蜜桃亚洲一二三四在线| 免费a在线观看播放| 日韩在线免费视频| 一级毛片免费毛片一级毛片免费 | AA免费观看的1000部电影| 永久免费av无码入口国语片| 男男gay做爽爽的视频免费| 久久狠狠爱亚洲综合影院| 亚洲av女电影网| 中文字幕精品亚洲无线码一区| 日本一道高清不卡免费| 无码日韩精品一区二区免费| 18禁成人网站免费观看|