【Android知识点精讲】(11)数据解析

来源:互联网 发布:淘宝全屏大图尺寸 编辑:程序博客网 时间:2024/06/16 07:19

文章出处:http://blog.csdn.net/scarthr/article/details/42344129

一 XML SAX解析

解析XML文件有SAX、PULL、DOM3种方式。由于DOM解析是比较浪费资源的,在手机端不推荐使用,我们这里就不介绍了。我们这里详细介绍一下SAX解析方式。
SAX解析是一边读取文件一边解析的方式,所以是一种比较不耗资源的解析方式。
用SAX解析,我们要继承DefaultHandler类,实现它的4个主要方法:
package com.thr.testxmlsax;import java.util.ArrayList;import java.util.List;import org.xml.sax.Attributes;import org.xml.sax.SAXException;import org.xml.sax.helpers.DefaultHandler;public class MySaxParser extends DefaultHandler {private List<Book> bookList;private Book book;private String tag;public List<Book> getBooks() {return bookList;}@Overridepublic void characters(char[] ch, int start, int length)throws SAXException {if ("name".equals(tag)) {book.setName(new String(ch, start, length));}}@Overridepublic void endElement(String uri, String localName, String qName)throws SAXException {if ("book".equals(localName)) {bookList.add(book);}tag = null;}@Overridepublic void startDocument() throws SAXException {bookList = new ArrayList<Book>();}@Overridepublic void startElement(String uri, String localName, String qName,Attributes attributes) throws SAXException {if ("book".equals(localName)) {book = new Book();book.setId(Integer.parseInt(attributes.getValue(0)));}tag = localName;}}
characters是在读取到xml文件标签外内容时执行的回调方法。
startDocument是开始读取xml文件的回调方法,我们在这里创建List集合
startElement是读取到一个标签开始节点的回调方法,每次在这个方法的结尾我们用一个tag来标记目前读取到的节点是什么。
endElement是读取到一个标签结束节点的回调方法。注意,在这个方法结束时,要将tag标签置空,负责他会记住上一个标签,并且读取到标签间隔中的空白字串时,会给上一个标签属性赋空值。
还有一点:关于localName、qName的解释,假如命名空间是local:blog的话,localName就是blog,qName就是local:blog(也就是全名)。明白了吧?
然后看怎么调用它:
//try {//InputStream is = getResources().openRawResource(R.raw.books);//MySaxParser mySaxParser = new MySaxParser();//Xml.parse(is, Xml.Encoding.UTF_8, mySaxParser);//List<Book> bookList = mySaxParser.getBooks();//for (Book book : bookList) {//Log.i(TAG, book.toString());//}//} catch (IOException e) {//e.printStackTrace();//} catch (SAXException e) {//e.printStackTrace();//}try {InputStream is = getResources().openRawResource(R.raw.books);MySaxParser mySaxParser = new MySaxParser();SAXParserFactory factory = SAXParserFactory.newInstance();SAXParser parser = factory.newSAXParser();parser.parse(is, mySaxParser);List<Book> bookList = mySaxParser.getBooks();for (Book book : bookList) {Log.i(TAG, book.toString());}} catch (ParserConfigurationException e) {e.printStackTrace();} catch (SAXException e) {e.printStackTrace();} catch (IOException e) {e.printStackTrace();}
这里有两种方法都可以解析,用哪个都行。

二 JSON

Json是一种比Xml使用更多的网络数据传输格式,
读取Json数据:android.util.JsonReader
写入Json数据:android.util.JsonWriter
Json可以存数据和对象,先来看一个简单的Json数据:
[{"id":"01","name":"第一"},{"id":"02","name":"第二"}]
最外层使用中括号包起来,里面每一个元素用大括号包起来,用逗号分隔。元素属性和值用冒号括起来,用冒号连接,每个属性用逗号分隔。

1. 写Json

这是一个写Json的例子:
package com.thr.testxmlsax;import java.io.File;import java.io.FileOutputStream;import java.io.IOException;import java.io.OutputStream;import java.io.OutputStreamWriter;import java.util.List;import android.util.JsonWriter;public class JsonWriterUtil {public void writeJson(File file, List<Book> bookList) throws IOException {FileOutputStream fos = new FileOutputStream(file);writeJsonStream(fos, bookList);}private void writeJsonStream(OutputStream out, List<Book> bookList)throws IOException {JsonWriter writer = new JsonWriter(new OutputStreamWriter(out, "utf-8"));writer.setIndent("");writeBookArray(writer, bookList);writer.close();}private void writeBookArray(JsonWriter writer, List<Book> bookList)throws IOException {writer.beginArray();for (Book book : bookList) {writeBook(writer, book);}writer.endArray();}private void writeBook(JsonWriter writer, Book book) throws IOException {writer.beginObject();writer.name("id").value(book.getId() + "");writer.name("name").value(book.getName());writer.endObject();}}
用setIndent写代码间距,开始写json使用beginArray方法,结束用endArray,写一个元素的开始用beginObject,结束用endOgject。

2. 读Json

这是一个读Json的例子:
package com.thr.testxmlsax;import java.io.IOException;import java.io.InputStream;import java.io.InputStreamReader;import java.util.ArrayList;import java.util.List;import android.util.JsonReader;public class JsonReaderUtil {public List<Book> readJson(InputStream in) throws IOException {List<Book> bookList = new ArrayList<Book>();JsonReader reader = new JsonReader(new InputStreamReader(in));bookList = readBookArray(reader);reader.close();return bookList;}private List<Book> readBookArray(JsonReader reader) throws IOException {List<Book> bookList = new ArrayList<Book>();reader.beginArray();while (reader.hasNext()) {bookList.add(readBook(reader));}reader.endArray();return bookList;}private Book readBook(JsonReader reader) throws IOException {Book book = new Book();reader.beginObject();while (reader.hasNext()) {String field = reader.nextName();if ("id".equals(field)) {book.setId(Integer.parseInt(reader.nextString()));} else if ("name".equals(field)) {book.setName(reader.nextString());} else {reader.skipValue();}}reader.endObject();return book;}}
这里注意在最后的readBook时候,需要定义一个field来存reader.nextName()的值,不然在同一个hasNext中,重复调用nextName是会报"Caused by: java.lang.IllegalStateException: Expected a name but was STRING"异常。
记住最后要加这两个权限:
    <!-- 往sdcard中写入数据的权限 -->    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />    <!-- 在sdcard中创建/删除文件的权限 -->    <uses-permission android:name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS" />

三 读写文件

读写文件的操作和Java中的益智,我们这里演示一个把资源图像文件写到SD卡中,然后在读取显示在ImageView中:
先是写文件的操作:
package com.thr.testxmlsax;import java.io.File;import java.io.FileInputStream;import java.io.FileNotFoundException;import java.io.FileOutputStream;import java.io.IOException;import java.io.InputStream;import android.graphics.Bitmap;import android.graphics.BitmapFactory;public class FileUtil {public static void write2SDCard(InputStream in) throws IOException {File file = new File("/mnt/sdcard/test.jpg");file.createNewFile();FileOutputStream out = new FileOutputStream("/mnt/sdcard/test.jpg");byte[] buffer = new byte[1024];int count = 0;while ((count = in.read(buffer)) != -1) {out.write(buffer, 0, count);}out.close();in.close();}public static Bitmap read2ImageView() throws FileNotFoundException {FileInputStream in = new FileInputStream(new File("/mnt/sdcard/test.jpg"));Bitmap bm = BitmapFactory.decodeStream(in);return bm;}}
一个读文件,一个写文件,非常简单,和Java中的处理一模一样。

源码下载

1 0
原创粉丝点击