前面我们总结了 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="xdwangiflytek@gmail.com" /> </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:xdwangiflytek@gmail.com
*
* @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:xdwangiflytek@gmail.com
*
* @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("xdwangiflytek@gmail.com");
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;
}
}