Android学习09-----Android中数据的存储和访问 (2) By 文件

前面我们总结了 SharedPerferences ,对于 SharedPerferences 我们可以方便的完成数据的存储功能,但是其只能保存一些简单的数据,如果想存更多类型的数据,则可以使用文件的存储操作,如果想要操作文件,则需要 Activity 类的支持。

Activity 类对文件操作的支持:

No.

方法

类型

描述

1

Public FileInputStream openFileInput(String name)

普通

设置要打开的文件输入流

2

Public FileOutputStream openFileOutput(String name,int mode)

普通

设置要打开文件的输出流,指定操作的模式,可以是 0 MODE_APPEND MODE_PRIVATE MODE_WORLD_READABLE MODE_WORLD_WRITEABLE

3

Public Resources getResources()

普通

返回 Resources 对象

回顾一下 IO 流输入 / 输出文件的流程:

· 使用 File 类定义一个要操作的文件;

· 使用字节流或字符流的子类为父类进行实例化,因为四个 IO 流的操作类都是抽象类;

· 完成输入 / 输出的功能;

· 关闭流;

一、文本文件

1 FileOutputStream 输出普通文件和 FileInputStream 读取文件

DataBakProject_File01_Activity.java

package com.iflytek.demo;

import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.PrintStream;
import java.util.Scanner;

import android.app.Activity;
import android.os.Bundle;
import android.widget.TextView;

public class DataBakProject_File01_Activity extends Activity {
	private static final String FILENAME = "xdwang.txt";// 设置文件名称
	private TextView msg = null; // 文本组件

	/** Called when the activity is first created. */
	@Override
	public void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.main);
		save();
		read();
	}

	private void save() {
		FileOutputStream outStream = null;// 接受文件输出对象
		try {
			outStream = super.openFileOutput(FILENAME, Activity.MODE_PRIVATE);
		} catch (FileNotFoundException e) {
			e.printStackTrace();
		}
		PrintStream out = new PrintStream(outStream);// 输出方便
		out.println("姓名:王旭东");
		out.println("年龄:23");
		out.close();// 资源一定要关闭
	}

	private void read() {
		this.msg = (TextView) super.findViewById(R.id.msg);
		FileInputStream input = null;
		try {
			input = super.openFileInput(FILENAME); // 取得输入流
		} catch (FileNotFoundException e) {
			e.printStackTrace();
		}
		Scanner scan = new Scanner(input);
		while (scan.hasNext()) {
			this.msg.append(scan.next() + "\n");
		}
		scan.close();
	}
}

以上程序考虑到用户要自定义保存目录,以及在“ sdcard ”上操作,所以本程序不太适合直接使用 Activity 类提供的文件操作的方法,用户可以直接使用最传统的 IO 流完成。

2 、向 sdcard 存储和读取文件

注意这里不能对文件的路径采用的硬编码的方式设置,因为这可能因为 sdcard 不存在而出现错误,即:最好的做法就是判断 sdcard 是否存在,如果存在则保存,如果不存在则提示用户“ sdcard ”不存在,无法保存,而要想完成这个判断的功能就必须通过 android.os.Environment 类取得目录的信息。

而一旦使用 Environment 类判断之后,那么这个类就会直接给用户一个路径,是给出的存储卡的路径。

DataBakProject_File02_Activity.java

package com.iflytek.demo;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.PrintStream;
import java.util.Scanner;

import android.app.Activity;
import android.os.Bundle;
import android.os.Environment;
import android.widget.TextView;
import android.widget.Toast;

public class DataBakProject_File02_Activity extends Activity {
	private static final String FILENAME = "xdwang.txt";// 设置文件名称
	private static final String DIR = "xdwang";// 操作文件夹的名称

	private TextView msg = null;

	/** Called when the activity is first created. */
	@Override
	public void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.main);

		this.msg = (TextView) super.findViewById(R.id.msg);

		// 判断sdcard是否存在,如果存在则输出目录的内容
		if (Environment.getExternalStorageState().equals(
				Environment.MEDIA_MOUNTED)) {
			String path = Environment.getExternalStorageDirectory()
					+ File.separator + DIR + File.separator + FILENAME;
			saveToSdcard(path);
			readFromSdcard(path);
		} else {
			Toast.makeText(this, "保存失败,SD卡不存在", Toast.LENGTH_LONG).show();
		}
	}

	private void saveToSdcard(String path) {
		File file = new File(path);// 定义要操作的文件
		if (!file.getParentFile().exists()) {
			file.getParentFile().mkdirs();// 创建父文件夹路径
		}
		PrintStream out = null;
		try {
			out = new PrintStream(new FileOutputStream(file));
			out.println("hello,android");
		} catch (FileNotFoundException e) {
			e.printStackTrace();
		} finally {
			if (out != null) {
				out.close();
			}
		}
	}

	private void readFromSdcard(String path) {
		File file = new File(path);// 定义要操作的文件
		if (!file.getParentFile().exists()) {
			file.getParentFile().mkdirs();// 创建父文件夹路径
		}
		Scanner scan = null;
		try {
			scan = new Scanner(new FileInputStream(file));
			while (scan.hasNext()) {
				this.msg.append(scan.next() + "\n");
			}
		} catch (Exception e) {
			e.printStackTrace();
		} finally { // 一定要关闭流
			if (scan != null) {
				scan.close();
			}
		}
	}
}

注意这里需要设置对 SDCard 操作的权限。

3 、读取资源文件

以上是保存文本文件,下面我们来说一下对资源文件的保存,在 Android 操作系统之中,也可以进行一些资源文件的读取,这些资源文件的 ID 都是自动的通过 R.java 这个类生成,如果要这些文件读取,使用 android.content.res.Resources 类即可完成

Resources 类的方法: public InputStream openRawResource(int id);

现在假设我们把一个资源文件保存在 res/raw 文件夹之中,注意这个资源文件的编码格式我们设定为 UTF-8

DataBakProject_File03_ResourcesActivity.java

package com.iflytek.demo;

import java.io.IOException;
import java.io.InputStream;
import java.util.Scanner;

import android.app.Activity;
import android.content.res.Resources;
import android.os.Bundle;
import android.widget.TextView;

public class DataBakProject_File03_ResourcesActivity extends Activity {
	private TextView msg = null;

	/** Called when the activity is first created. */
	@Override
	public void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.main);
		this.msg = (TextView) super.findViewById(R.id.msg);
		Resources res = super.getResources(); // 资源操作类
		InputStream input = res.openRawResource(R.raw.resources); // 为要读取的内容设置输入流
		Scanner scan = new Scanner(input);
		StringBuffer buf = new StringBuffer();
		while (scan.hasNext()) {
			buf.append(scan.next()).append("\n");
		}
		scan.close();
		try {
			input.close();
		} catch (IOException e) {
			e.printStackTrace();
		}
		this.msg.setText(buf);
	}
}

二、 XML 文件

使用文件保存数据固然很方便,但是如果现在数据较多的话,则管理起来就不方便了,所以在使用文件保存的时候,也往往会采用 XML 文件形式进行数据的保存,而一旦使用 XML 操作,那么就肯定需要对 XML 文件进行解析,而 DOM 解析就是最常见的一种。

1 DOM 操作 XML 文件

DataBakProject_XML01_DOMActivity.java

package com.iflytek.demo;

import java.io.File;
import java.io.IOException;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.transform.OutputKeys;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerConfigurationException;
import javax.xml.transform.TransformerException;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;

import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.NodeList;
import org.xml.sax.SAXException;

import android.app.Activity;
import android.os.Bundle;
import android.os.Environment;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;

public class DataBakProject_XML01_DOMActivity extends Activity {
	private EditText name = null;
	private EditText email = null;
	private Button but_save = null;
	private Button but_read = null;
	private TextView result = null;

	/** Called when the activity is first created. */
	@Override
	public void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.main);

		this.name = (EditText) super.findViewById(R.id.name);
		this.email = (EditText) super.findViewById(R.id.email);
		this.but_save = (Button) super.findViewById(R.id.but_save);
		this.but_read = (Button) super.findViewById(R.id.but_read);
		this.result = (TextView) super.findViewById(R.id.result);
		this.but_save.setOnClickListener(new OnClickSaveListenerImpl());
		this.but_read.setOnClickListener(new OnClickReadListenerImpl());
	}

	private class OnClickSaveListenerImpl implements OnClickListener {

		@Override
		public void onClick(View v) {
			if (!Environment.getExternalStorageState().equals(
					Environment.MEDIA_MOUNTED)) { // 不存在不操作
				return; // 返回到程序的被调用处
			}
			File file = new File(Environment.getExternalStorageDirectory()
					+ File.separator + "xdwang" + File.separator + "test.xml"); // 要输出文件的路径
			if (!file.getParentFile().exists()) { // 父路径不存在
				file.getParentFile().mkdirs(); // 创建父文件夹
			}
			DocumentBuilderFactory factory = DocumentBuilderFactory
					.newInstance();
			DocumentBuilder builder = null;
			try {
				builder = factory.newDocumentBuilder();
			} catch (ParserConfigurationException e) {
				e.printStackTrace();
			}
			Document doc = null;
			doc = builder.newDocument(); // 创建一个新的文档
			Element addresslist = doc.createElement("addresslist");
			Element linkman = doc.createElement("linkman");
			Element name = doc.createElement("name");
			Element email = doc.createElement("email");
			name.appendChild(doc
					.createTextNode(DataBakProject_XML01_DOMActivity.this.name
							.getText().toString()));
			email.appendChild(doc
					.createTextNode(DataBakProject_XML01_DOMActivity.this.email
							.getText().toString()));
			linkman.appendChild(name);
			linkman.appendChild(email);
			addresslist.appendChild(linkman);
			doc.appendChild(addresslist);
			TransformerFactory tf = TransformerFactory.newInstance();
			Transformer transformer = null;
			try {
				transformer = tf.newTransformer();
			} catch (TransformerConfigurationException e) {
				e.printStackTrace();
			}
			transformer.setOutputProperty(OutputKeys.ENCODING, "GBK");
			DOMSource source = new DOMSource(doc);
			StreamResult result = new StreamResult(file);
			try {
				transformer.transform(source, result);
			} catch (TransformerException e) {
				e.printStackTrace();
			}
		}

	}

	private class OnClickReadListenerImpl implements OnClickListener {

		@Override
		public void onClick(View v) {
			if (!Environment.getExternalStorageState().equals(
					Environment.MEDIA_MOUNTED)) { // 不存在不操作
				return; // 返回到程序的被调用处
			}
			File file = new File(Environment.getExternalStorageDirectory()
					+ File.separator + "xdwang" + File.separator + "test.xml"); // 要输出文件的路径
			if (!file.exists()) { // 文件不存在
				return;
			}
			DocumentBuilderFactory factory = DocumentBuilderFactory
					.newInstance();
			DocumentBuilder builder = null;
			try {
				builder = factory.newDocumentBuilder();
			} catch (ParserConfigurationException e) {
				e.printStackTrace();
			}
			Document doc = null;
			try {
				doc = builder.parse(file); // 通过文件转化文档
			} catch (SAXException e1) {
				e1.printStackTrace();
			} catch (IOException e1) {
				e1.printStackTrace();
			}
			NodeList nl = doc.getElementsByTagName("linkman");
			for (int x = 0; x < nl.getLength(); x++) {
				Element e = (Element) nl.item(x); // 取得元素
				DataBakProject_XML01_DOMActivity.this.result.setText(e
						.getElementsByTagName("name").item(0).getFirstChild()
						.getNodeValue()
						+ e.getElementsByTagName("email").item(0)
								.getFirstChild().getNodeValue());
			}
		}
	}
}

main.xml

<?xml version="1.0" encoding="utf-8"?>
<TableLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:orientation="vertical" >

    <TableRow >

        <TextView
            android:layout_width="fill_parent"
            android:layout_height="wrap_content"
            android:text="姓名:"
            android:textSize="20px" />

        <EditText
            android:id="@+id/name"
            android:layout_width="fill_parent"
            android:layout_height="wrap_content"
            android:text="王旭东" />
    </TableRow>

    <TableRow >

        <TextView
            android:layout_width="fill_parent"
            android:layout_height="wrap_content"
            android:text="邮箱:"
            android:textSize="20px" />

        <EditText
            android:id="@+id/email"
            android:layout_width="fill_parent"
            android:layout_height="wrap_content"
            android:text="[email protected]" />
    </TableRow>

    <TableRow >

        <Button
            android:id="@+id/but_save"
            android:layout_width="fill_parent"
            android:layout_height="wrap_content"
            android:text="保存" />

        <Button
            android:id="@+id/but_read"
            android:layout_width="fill_parent"
            android:layout_height="wrap_content"
            android:text="读取" />
    </TableRow>

    <TableRow >

        <TextView
            android:id="@+id/result"
            android:layout_width="fill_parent"
            android:layout_height="wrap_content"
            android:textSize="20px" />
    </TableRow>

</TableLayout>

2 SAX 解析

DOM 解析本身可以支持文件的读取和修改,但是 DOM 本身有一个最大的问题就在于 DOM 操作之中所有的内容要一次性全部读取出来,如果文件的内容较大的话,这种读取就不可取了。所以这个使用一个我们可以使用 SAX 解析。

如果要想使用 SAX 解析之前的文件,那么就首先需要定义一个保存数据的类。

LinkMan.java

package com.iflytek.demo;

public class LinkMan {

	private String name;
	private String email;

	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}

	public String getEmail() {
		return email;
	}

	public void setEmail(String email) {
		this.email = email;
	}

}

每一个 LinkMan 类的对象都表示一条 linkman 节点的内容。

SAX 解析肯定首先需要一个解析器,继承自 DefaultHandler

MySAX.java

package com.iflytek.demo;

import java.util.ArrayList;
import java.util.List;

import org.xml.sax.Attributes;
import org.xml.sax.SAXException;
import org.xml.sax.helpers.DefaultHandler;

/**
 * 
 * @author xdwang 
 *
 * @create 2012-10-6 上午9:25:54
 * 
 * @email:[email protected]
 * 
 * @description SAX解析器
 *
 */
public class MySAX extends DefaultHandler {
	private List<LinkMan> all = null; // 保存多条数据
	private LinkMan man = null;
	private String elementName = null; // 保存节点的名称

	@Override
	public void characters(char[] ch, int start, int length)
			throws SAXException {
		if (this.elementName != null) { // 已经取得了元素名称
			String data = new String(ch, start, length);
			if ("name".equals(this.elementName)) {
				this.man.setName(data);
			} else if ("email".equals(this.elementName)) {
				this.man.setEmail(data);
			}
		}
	}

	@Override
	public void endElement(String uri, String localName, String qName)
			throws SAXException {
		if ("linkman".equals(localName)) {
			this.all.add(this.man);
			this.man = null; // 准备保存下次的数据
		}
		this.elementName = null;// 把元素名称清空
	}

	@Override
	public void startDocument() throws SAXException {
		this.all = new ArrayList<LinkMan>(); // 表示开始解析文档,所以要设置集合
	}

	@Override
	public void startElement(String uri, String localName, String qName,
			Attributes attributes) throws SAXException {
		if ("linkman".equals(localName)) { // 是一个linkman节点
			this.man = new LinkMan(); // 实例化LinkMan对象
		}
		this.elementName = localName; // 保存元素名称
	}

	public List<LinkMan> getAll() {
		return all;
	}

}

DataBakProject_XML02_SAXActivity.java

package com.iflytek.demo;

import java.io.File;
import java.io.IOException;
import java.util.List;

import javax.xml.parsers.ParserConfigurationException;
import javax.xml.parsers.SAXParser;
import javax.xml.parsers.SAXParserFactory;

import org.xml.sax.SAXException;

import android.app.Activity;
import android.os.Bundle;
import android.os.Environment;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.TextView;

public class DataBakProject_XML02_SAXActivity extends Activity {
	private TextView name = null;
	private TextView email = null;
	private Button but = null;

	/** Called when the activity is first created. */
	@Override
	public void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.main);
		this.name = (TextView) super.findViewById(R.id.name);
		this.email = (TextView) super.findViewById(R.id.email);
		this.but = (Button) super.findViewById(R.id.but);
		this.but.setOnClickListener(new OnClickListenerImpl());
	}

	private class OnClickListenerImpl implements OnClickListener {

		@Override
		public void onClick(View v) {
			if (!Environment.getExternalStorageState().equals(
					Environment.MEDIA_MOUNTED)) { // 不存在不操作
				return; // 返回到程序的被调用处
			}
			File file = new File(Environment.getExternalStorageDirectory()
					+ File.separator + "xdwang" + File.separator + "test.xml"); // 要输出文件的路径
			if (!file.exists()) { // 文件不存在
				return;
			}
			SAXParserFactory factory = SAXParserFactory.newInstance();
			SAXParser parser = null;
			MySAX sax = new MySAX();
			try {
				parser = factory.newSAXParser();
			} catch (ParserConfigurationException e) {
				e.printStackTrace();
			} catch (SAXException e) {
				e.printStackTrace();
			}
			try {
				parser.parse(file, sax);
			} catch (SAXException e) {
				e.printStackTrace();
			} catch (IOException e) {
				e.printStackTrace();
			}
			List<LinkMan> all = sax.getAll();
			System.out.println(all.size());
			if (all.size() > 0) {
				DataBakProject_XML02_SAXActivity.this.name.setText(all.get(0)
						.getName());
				DataBakProject_XML02_SAXActivity.this.email.setText(all.get(0)
						.getEmail());
			} else {
				DataBakProject_XML02_SAXActivity.this.name.setText("无数据");
				DataBakProject_XML02_SAXActivity.this.email.setText("无数据");
			}
		}

	}
}

注意这里的 xml 文件中不要出现中文,并且格式为 UTF-8

3 XML Pull 解析

在使用 JavaEE 进行项目开发中,很多情况下 DOM SAX 使用各有特点,而本身也都各有各自的应用范畴,所以在 Java 之中专门有 JDOM DOM4J 组件供用户使用,但是这个组件到了 Android 中就没有了。

Android 之中为了方便用户的 XML 操作,专门提供了 XMLPull 解析的方式。如果想要完成 XMLPull 解析处理需要 org.xmlpull.v1.XmlPullParserFactory 类和 org.xmlpull.v1.XmlPullParser 接口的支持 XmlPullParserFactory 类的主要功能是可以通过里面提供的 newPullParser() 方法取得一个 XmlPullParser 接口的对象。

要想使用 XMLPull 的解析方式,也需要一个专门的工具类。

MyXMLPullUtil.java

package com.iflytek.demo;

import java.io.InputStream;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

import org.xmlpull.v1.XmlPullParser;
import org.xmlpull.v1.XmlPullParserFactory;
import org.xmlpull.v1.XmlSerializer;

/**
 * 
 * @author xdwang 
 *
 * @create 2012-10-9 下午10:37:14
 * 
 * @email:[email protected]
 * 
 * @description XMLPull解析工具类
 *
 */
public class MyXMLPullUtil {

	private List<LinkMan> all = null;
	private OutputStream output = null;

	private InputStream input = null;

	public MyXMLPullUtil(OutputStream output, List<LinkMan> all) {
		this.output = output;
		this.all = all;
	}

	public MyXMLPullUtil(InputStream input) {
		this.input = input;
	}

	/**
	 * @descrption 写入
	 * @author xdwang
	 * @create 2012-10-9下午10:27:36
	 * @throws Exception
	 */
	public void writeByXMLPull() throws Exception {
		XmlPullParserFactory factory = XmlPullParserFactory.newInstance();
		XmlSerializer xs = factory.newSerializer();
		xs.setOutput(this.output, "UTF-8");
		xs.startDocument("UTF-8", true);
		xs.startTag(null, "addresslist");// 根元素
		Iterator<LinkMan> iter = this.all.iterator();
		while (iter.hasNext()) {
			LinkMan man = iter.next();
			xs.startTag(null, "linkman");
			xs.startTag(null, "name");
			xs.text(man.getName());
			xs.endTag(null, "name");
			xs.startTag(null, "email");
			xs.text(man.getEmail());
			xs.endTag(null, "email");
			xs.endTag(null, "linkman");
		}
		xs.endTag(null, "addresslist");
		xs.endDocument();
		xs.flush();
	}

	/**
	 * @descrption 读取
	 * @author xdwang
	 * @create 2012-10-9下午10:34:27
	 * @return
	 * @throws Exception
	 */
	public List<LinkMan> readByXMLPull() throws Exception {
		List<LinkMan> all = null;
		LinkMan man = null;
		String elementName = null; // 保存节点的名称
		XmlPullParserFactory factory = XmlPullParserFactory.newInstance();// 取得XmlPullParserFactory类对象
		XmlPullParser xmlPullParser = factory.newPullParser();// 取得XmlPullParser接口对象
		xmlPullParser.setInput(this.input, "UTF-8");
		int eventType = xmlPullParser.getEventType(); // 取得事件码
		while (eventType != XmlPullParser.END_DOCUMENT) { // 不是文档底部
			if (eventType == XmlPullParser.START_DOCUMENT) { // 文档开始
				all = new ArrayList<LinkMan>();
			} else if (eventType == XmlPullParser.START_TAG) { // 元素标记开始
				elementName = xmlPullParser.getName(); // 取得元素的名称
				if ("linkman".equals(elementName)) {
					man = new LinkMan();
				}
			} else if (eventType == XmlPullParser.END_TAG) { // 结束元素
				elementName = xmlPullParser.getName(); // 取得节点名称
				if ("linkman".equals(elementName)) {
					all.add(man);
					man = null;
				}
			} else if (eventType == XmlPullParser.TEXT) { // 数据
				if ("name".equals(elementName)) {
					man.setName(xmlPullParser.getText());
				} else if ("email".equals(elementName)) {
					man.setEmail(xmlPullParser.getText());
				}
			}
			eventType = xmlPullParser.next(); // 取得下一个事件码
		}
		return all;
	}
}

工具类完成之后,对于以后的程序也同样使用 List 取得解析后的结果。

XMLPullActivity.java

package com.iflytek.demo;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.List;

import android.app.Activity;
import android.os.Bundle;
import android.os.Environment;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.TextView;

public class XMLPullActivity extends Activity {

	private TextView name = null;
	private TextView email = null;
	private Button but_read = null;

	/** Called when the activity is first created. */
	@Override
	public void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.main);
		
		writeByXMLPull();
		
		readByXMLPull();

	}

	/**
	 * @descrption 写入
	 * @author xdwang
	 * @create 2012-10-9下午10:32:46
	 */
	private void writeByXMLPull() {
		if (!Environment.getExternalStorageState().equals(
				Environment.MEDIA_MOUNTED)) { // 不存在不操作
			return; // 返回到程序的被调用处
		}
		File file = new File(Environment.getExternalStorageDirectory()
				+ File.separator + "xdwang" + File.separator + "test.xml"); // 要输出文件的路径
		if (!file.getParentFile().exists()) { // 文件不存在
			file.getParentFile().mkdirs(); // 创建文件夹
		}
		List<LinkMan> all = new ArrayList<LinkMan>();
		for (int x = 0; x < 3; x++) {
			LinkMan man = new LinkMan();
			man.setName("xdwang - " + x);
			man.setEmail("[email protected]");
			all.add(man);
		}
		OutputStream output = null;
		try {
			output = new FileOutputStream(file);
			new MyXMLPullUtil(output, all).writeByXMLPull();
		} catch (Exception e) {
		} finally {
			if (output != null) {
				try {
					output.close();
				} catch (IOException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
			}
		}
	}

	/**
	 * @descrption 读取
	 * @author xdwang
	 * @create 2012-10-9下午10:32:23
	 */
	private void readByXMLPull() {
		this.name = (TextView) super.findViewById(R.id.name);
		this.email = (TextView) super.findViewById(R.id.email);
		this.but_read = (Button) super.findViewById(R.id.but);
		this.but_read.setOnClickListener(new OnClickListenerImpl());
	}

	private class OnClickListenerImpl implements OnClickListener {
		@Override
		public void onClick(View v) {
			if (!Environment.getExternalStorageState().equals(
					Environment.MEDIA_MOUNTED)) { // 不存在不操作
				return; // 返回到程序的被调用处
			}
			File file = new File(Environment.getExternalStorageDirectory()
					+ File.separator + "xdwang" + File.separator + "test.xml"); // 要输出文件的路径
			if (!file.exists()) { // 文件不存在
				return;
			}
			try {
				InputStream input = new FileInputStream(file);
				MyXMLPullUtil util = new MyXMLPullUtil(input);
				List<LinkMan> all = util.readByXMLPull();
				XMLPullActivity.this.name.setText(all.get(0).getName());
				XMLPullActivity.this.email.setText(all.get(0).getEmail());
			} catch (Exception e) {
				e.printStackTrace();
			}
		}

	}
}

4 JSON 解析

在之前都是使用 XML 风格的文件来保存了一些操作数据,但是这种通过 XML 文件完成的数据的保存本身却存在着一些问题。比如存在很多相同的标签,即除了真正的数据之外,还要传递一系列的非主要数据。

JSON 采用完全独立于语言平台的文本格式(这点与 XML 类似),使用 JSON 可以将对象中表示的一组数据转换为字符串,然后可以在各个应用程序之间传递这些字符串,或者在异步系统中进行服务器和客户端之间的数据传递。

JSON 操作本身有其自己的数据格式,这些数据格式,用户可以自己使用字符串拼凑,也可以直接利用 JSON 给出的操作类完成,而在 Android 系统中, JSON 操作所需要的数据包已经默认集成了,所以用户不需要额外的导包进行开发了。

package com.iflytek.demo;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.FileReader;
import java.io.PrintStream;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;

import android.app.Activity;
import android.os.Bundle;
import android.os.Environment;
import android.widget.TextView;

public class JSONActivity extends Activity {
	private String nameData[] = new String[] { "小王", "小李", "小张" };
	private int ageData[] = new int[] { 23, 25, 27 };
	private boolean isMarraiedData[] = new boolean[] { false, true, false };
	private double salaryData[] = new double[] { 7000.0, 5000.0, 3000.0 };
	private Date birthdayData[] = new Date[] { new Date(), new Date(),
			new Date() };
	private String companyName = "微软亚洲研究院";
	private String companyAddr = "中国北京";
	private String companyTel = "010-52354396";

	private TextView msg = null;

	/** Called when the activity is first created. */
	@Override
	public void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.main);
		writeByJSON();
		readByJSON();

	}

	/**
	 * @descrption 写入
	 * @author xdwang
	 * @create 2012-10-9下午11:00:04
	 */
	private void writeByJSON() {
		JSONObject jsonObject = new JSONObject(); // 建立最外面的节点对象
		JSONArray jsonArray = new JSONArray(); // 定义数组
		for (int x = 0; x < nameData.length; x++) { // 将数组内容配置到相应的节点
			JSONObject temp = new JSONObject(); // 每一个包装的数据都是JSONObject
			try {
				temp.put("name", this.nameData[x]);
				temp.put("age", this.ageData[x]);
				temp.put("married", this.isMarraiedData[x]);
				temp.put("salary", this.salaryData[x]);
				temp.put("birthday", this.birthdayData[x]);
			} catch (JSONException e) {
				e.printStackTrace();
			}
			jsonArray.put(temp); // 保存多个JSONObject
		}
		try {
			jsonObject.put("persondata", jsonArray);
			jsonObject.put("company", this.companyName);
			jsonObject.put("address", this.companyAddr);
			jsonObject.put("telephone", this.companyTel);
		} catch (JSONException e) {
			e.printStackTrace();
		}
		if (!Environment.getExternalStorageState().equals(
				Environment.MEDIA_MOUNTED)) { // 不存在不操作
			return; // 返回到程序的被调用处
		}
		File file = new File(Environment.getExternalStorageDirectory()
				+ File.separator + "xdwang" + File.separator + "json.txt"); // 要输出文件的路径
		if (!file.getParentFile().exists()) { // 文件不存在
			file.getParentFile().mkdirs(); // 创建文件夹
		}
		PrintStream out = null;
		try {
			out = new PrintStream(new FileOutputStream(file));
			out.print(jsonObject.toString()); // 将数据变为字符串后保存
		} catch (FileNotFoundException e) {
			e.printStackTrace();
		} finally {
			if (out != null) {
				out.close(); // 关闭输出
			}
		}

	}

	/**
	 * @descrption 读取
	 * @author xdwang
	 * @create 2012-10-9下午10:20:23
	 */
	private void readByJSON() {

		this.msg = (TextView) super.findViewById(R.id.msg);

		if (!Environment.getExternalStorageState().equals(
				Environment.MEDIA_MOUNTED)) { // 不存在不操作
			return; // 返回到程序的被调用处
		}
		File file = new File(Environment.getExternalStorageDirectory()
				+ File.separator + "xdwang" + File.separator + "json.txt"); // 要输出文件的路径
		if (!file.exists()) { // 文件不存在
			return;
		}

		BufferedReader reader = null;
		String str = "";
		try {
			reader = new BufferedReader(new FileReader(file));
			String tempString = null;

			while ((tempString = reader.readLine()) != null) {
				str = str + tempString;
			}
			reader.close();
		} catch (Exception e) {
		} finally {
			if (reader != null) {
				try {
					reader.close();
				} catch (Exception e) {
				}
			}
		}

		StringBuffer buf = new StringBuffer();
		try {
			Map<String, Object> result = this.parseJson(str); // 解析文本
			buf.append("公司名称:" + result.get("company") + "\n");
			buf.append("电话号码:" + result.get("telephone") + "\n");
			buf.append("公司地址:" + result.get("address") + "\n");
			List<Map<String, Object>> all = (List<Map<String, Object>>) result
					.get("persondata");
			Iterator<Map<String, Object>> iter = all.iterator();
			while (iter.hasNext()) {
				Map<String, Object> map = iter.next();
				buf.append("姓名:" + map.get("name") + ",年龄:" + map.get("age")
						+ "\n" + "工资:" + map.get("salary") + ",是否结婚:"
						+ map.get("married") + "\n" + "生日:"
						+ map.get("birthday") + "\n");
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
		this.msg.setText(buf);
	}

	private Map<String, Object> parseJson(String data) throws Exception {
		Map<String, Object> maps = new HashMap<String, Object>();
		JSONObject jsonObject = new JSONObject(data); // 全部的内容变为一个项
		maps.put("company", jsonObject.getString("company")); // 取出项
		maps.put("telephone", jsonObject.getString("telephone")); // 取出项
		maps.put("address", jsonObject.getString("address")); // 取出项
		JSONArray jsonArray = jsonObject.getJSONArray("persondata"); // 取出数组
		List<Map<String, Object>> lists = new ArrayList<Map<String, Object>>();
		for (int x = 0; x < jsonArray.length(); x++) {
			Map<String, Object> map = new HashMap<String, Object>();
			JSONObject jsonObj = jsonArray.getJSONObject(x);
			map.put("name", jsonObj.getString("name"));
			map.put("age", jsonObj.getInt("age"));
			map.put("salary", jsonObj.getDouble("salary"));
			map.put("married", jsonObj.getBoolean("married"));
			map.put("birthday", jsonObj.getString("birthday"));
			lists.add(map);
		}
		maps.put("persondata", lists);
		return maps;
	}
}

猜你喜欢

转载自xdwangiflytek.iteye.com/blog/1694480