xdwangiflytek 发表于 2013-1-14 17:55:57

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

前面我们总结了SharedPerferences,对于SharedPerferences我们可以方便的完成数据的存储功能,但是其只能保存一些简单的数据,如果想存更多类型的数据,则可以使用文件的存储操作,如果想要操作文件,则需要Activity类的支持。
         Activity类对文件操作的支持:
No.
方法
类型
描述
1
Public FileInputStreamopenFileInput(String name)
普通
设置要打开的文件输入流
2
Public FileOutputStream openFileOutput(Stringname,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. */@Overridepublic 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. */@Overridepublic 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类的方法:publicInputStream 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. */@Overridepublic 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. */@Overridepublic 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 {@Overridepublic 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 {@Overridepublic 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; // 保存节点的名称@Overridepublic 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);}}}@Overridepublic 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;// 把元素名称清空}@Overridepublic void startDocument() throws SAXException {this.all = new ArrayList<LinkMan>(); // 表示开始解析文档,所以要设置集合}@Overridepublic 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. */@Overridepublic 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 {@Overridepublic 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. */@Overridepublic 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 blocke.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 {@Overridepublic 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. */@Overridepublic 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(); // 每一个包装的数据都是JSONObjecttry {temp.put("name", this.nameData);temp.put("age", this.ageData);temp.put("married", this.isMarraiedData);temp.put("salary", this.salaryData);temp.put("birthday", this.birthdayData);} 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;}} 
 
页: [1]
查看完整版本: Android学习09-----Android中数据的存储和访问 (2) By 文件