1. 程式人生 > >讀取assets下的配置檔案

讀取assets下的配置檔案

這裡講assets或者res/raw中的資源也當做成一種儲存資源。只是這個儲存資源是在程式執行之前就儲存好了的。比如,app需要所有的城市和城市的編碼,用於使用者的選擇當前城市。這個時候的所有的城市列表從網路當中獲取,不太合適,還不如自己在儲存一個xml格式的檔案,其中有所有的城市列表。從中讀取出來。再比如,在實際開發中,後臺只傳來了一些ABC001,ABC002,這樣的編碼,需要自己去儲存一個關係,一個字典。最簡單的方式是直接在程式碼中寫死,這個不推薦,資料一多,程式碼就會很長,直接寫死,讓人感覺是個很low的寫法,這個時候就去做一個xml配置檔案。其實,實際開發中,有很多需要自己寫一個配置檔案的,而這些配置檔案就可以使用xml格式,並儲存在assets上。也可以放入raw中。

那麼先比較一些assets和res/raw有什麼區別?

*res/raw和assets的相同點:

1.兩者目錄下的檔案在打包後會原封不動的儲存在apk包中,不會被編譯成二進位制。


*res/raw和assets的不同點:
1.res/raw中的檔案會被對映到R.java檔案中,訪問的時候直接使用資源ID即R.id.filename;assets資料夾下的檔案不會被對映到R.java中,訪問的時候需要AssetManager類。
2.res/raw不可以有目錄結構,而assets則可以有目錄結構,也就是assets目錄下可以再建立資料夾

*讀取檔案資源:

1.讀取res/raw下的檔案資源,通過以下方式獲取輸入流來進行寫操作

  • InputStream is = getResources().openRawResource(R.raw.filename);  

2.(1)讀取assets下的檔案資源,通過以下方式獲取輸入流來進行寫操作

  • AssetManager am =null;  
  • am = getAssets();  
  • InputStream is = am.open("filename");  

  (2)如果用Videoview來播放:

  VideoView.setVideoUri(Uri.parse("android.resource://" + getpackageName() + "/" + R.raw.movie));

注意1:Google的Android系統處理Assert有個bug,在AssertManager中不能處理單個超過1MB的檔案,不然會報異常,raw沒這個限制可以放個4MB的Mp3檔案沒問題。

注意2:assets 資料夾是存放不進行編譯加工的原生檔案,即該資料夾裡面的檔案不會像 xml, java 檔案被預編譯,可以存放一些圖片,html,js, css 等檔案。

接下來如何對獲取xml檔案進行解析這裡講介紹sax和pull解析方式。

首先來看Sax解析。

<?xml version="1.0" encoding="utf-8"?>
<city>
    <country id="420100" name="武漢市"/>
    <country id="420200" name="黃石市"/>
    <country id="420300" name="十堰市"/>
    <country id="420500" name="宜昌市"/>
    <country id="420600" name="襄陽市"/>
    <country id="420700" name="鄂州市"/>
    <country id="420800" name="荊門市"/>
    <country id="420900" name="孝感市"/>
    <country id="421000" name="荊州市"/>
    <country id="421100" name="黃岡市"/>
    <country id="421200" name="咸寧市"/>
    <country id="421300" name="隨州市"/>
    <country id="422800" name="恩施州"/>
    <country id="429004" name="仙桃市"/>
    <country id="429005" name="潛江市"/>
    <country id="429006" name="天門市"/>
    <country id="429021" name="神農架林區"/>
    <country id="429900" name="省直"/>
</city>
並見一個實體類
public class CityBean {
    private String cityId;
    private String cityName;

    public String getCityId() {
        return cityId;
    }

    public void setCityId(String cityId) {
        this.cityId = cityId;
    }

    public String getCityName() {
        return cityName;
    }

    public void setCityName(String cityName) {
        this.cityName = cityName;
    }
}
建立之後,這裡直接給出程式碼
public class CitySaxParseHandler extends DefaultHandler{
    private ArrayList<CityBean> mCityBeen;
    private CityBean city;

    private String tagName;

    public static ArrayList<CityBean> getProvicenModel(InputStream in) throws Exception {
        //獲取SAXParseFactory工廠
        SAXParserFactory factory = SAXParserFactory.newInstance();

        //獲取解析器
        SAXParser parser = factory.newSAXParser();

        //獲取xml讀取器
        XMLReader reader = parser.getXMLReader();

        //將InputStream流包裝成InputSource
        InputSource is = new InputSource(in);

        //獲取DefaultHandler
        CitySaxParseHandler handler = new CitySaxParseHandler();

        //讀取器設定內容
        reader.setContentHandler(handler);

        //解析流
        reader.parse(is);

        return handler.mCityBeen;
    }<span style="white-space:pre">																</span>//當SAX解析器開始解析xml呼叫該方法
    @Override
    public void startDocument() throws SAXException {
        super.startDocument();

    }
    //當sax解析器解析到xml文件結束時呼叫
    @Override
    public void endDocument() throws SAXException {
        super.endDocument();
    }
    //解析到開始標籤的時候呼叫如解析到<city>
    @Override
    public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException {
        super.startElement(uri, localName, qName, attributes);
        this.tagName = localName;
        if (tagName.equalsIgnoreCase("city")){
            mCityBeen = new ArrayList<>();
        }else if(tagName.equalsIgnoreCase("country")){
            city = new CityBean();
            city.setCityId(attributes.getValue("id"));
            city.setCityName(attributes.getValue("name"));
        }
    }
    //解析到結束標籤的時候呼叫如</city>
    @Override
    public void endElement(String uri, String localName, String qName) throws SAXException {
        super.endElement(uri, localName, qName);
        this.tagName = null;
        if (localName.equalsIgnoreCase("city")){

        }else if(localName.equalsIgnoreCase("country")){
            mCityBeen.add(city);
            city = null;
        }
    }

    @Override
    public void characters(char[] ch, int start, int length) throws SAXException {
        super.characters(ch, start, length);
    }
}

來看看getProvicenModel()裡面的步驟如下:

1、例項化一個工廠SAXParserFactory

2、例項化SAXPraser物件,建立XMLReader 解析器

3、例項化handler,處理器

4、解析器註冊一個事件

4、讀取檔案流

5、解析檔案

接下下看看pull解析方式,
public List<CityBean> parseXml(InputStream in) throws Exception{
        List<CityBean> cityBeenList = null ;
        CityBean city = null;

        XmlPullParser xmlPullParser = Xml.newPullParser();
        xmlPullParser.setInput(in,"UTF-8");
        int eventType = xmlPullParser.getEventType();

        while (eventType != XmlPullParser.END_DOCUMENT){
            switch (eventType){
                case XmlPullParser.START_DOCUMENT:                              //文件開始

                    break;
                case XmlPullParser.START_TAG:                                   //開始標籤
                    if ("city".equalsIgnoreCase(xmlPullParser.getName())){
                        cityBeenList = new ArrayList<>();
                    }else if("country".equalsIgnoreCase(xmlPullParser.getName())){
                        city = new CityBean();
                        //如果xml檔案<city>武漢</city>,這裡xmlPullParser.getText();獲取其值
                        city.setCityId(xmlPullParser.getAttributeValue(null,"id"));
                        city.setCityName(xmlPullParser.getAttributeValue(null,"name"));
                    }
                    break;
                case XmlPullParser.END_TAG:                                         //結束標籤
                    if ("city".equalsIgnoreCase(xmlPullParser.getName())){

                    } else if ("country".equalsIgnoreCase(xmlPullParser.getName())){
                        cityBeenList.add(city);
                        city = null;
                    }
                    break;
            }
            eventType = xmlPullParser.next();           // 進入下一個元素並觸發相應事件
        }

        return cityBeenList;
    }

assets res/raw檔案就到這裡,下面一個工具類,就是獲取其中的資源並轉化成字串。

public class ResourceUtil {

    /**
     * 讀取assets中的檔案
     * @param fileName 檔名
     * @return
     */
    public static String getFileFromAssets(String fileName) {

        if (TextUtils.isEmpty(fileName)) {
            return null;
        }

        try {
            StringBuilder sb = new StringBuilder("");
            InputStreamReader in = new InputStreamReader(SheBaoApp.getContext().getResources().getAssets().open(fileName));
            BufferedReader br = new BufferedReader(in);
            String line;
            while ((line = br.readLine()) != null) {
                sb.append(line);
            }
            return sb.toString();
        } catch (IOException e) {
            e.printStackTrace();
            return null;
        }
    }

    /**
     * 讀取raw中的檔案
     * @param resid
     * @return
     */
    public static String getFileFromRaw(int resid) {

        try {
            StringBuffer sb = new StringBuffer("");
            InputStreamReader in = new InputStreamReader(SheBaoApp.getContext().getResources().openRawResource(resid));
            BufferedReader br = new BufferedReader(in);
            String line;
            while ((line = br.readLine()) != null) {
                sb.append(line);
            }
            return  sb.toString();
        } catch (IOException e) {
            e.printStackTrace();
            return null;
        }
    }

    public static InputStream getAssert(Context context,String name){
        try {
            InputStream inputStream = context.getAssets().open(name);
            return inputStream;
        } catch (IOException e) {
            e.printStackTrace();
        }
        return null;
    }
}