`

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="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;
	}
}

 

 

分享到:
评论

相关推荐

    Android学习09-----Android中数据的存储和访问 (3) By SQLite

    这篇博客“Android学习09-----Android中数据的存储和访问 (3) By SQLite”深入探讨了如何利用SQLite进行数据管理。 SQLite是一种关系型数据库管理系统,它嵌入到应用程序中,不需要单独的服务或进程来运行。在...

    Android高级编程--源代码

    在每章的讲解中,它会让你通过一系列示例项目逐步掌握Android中的各种新功能和技术,助你取得最圆满的学习效果。本书所介绍的各个应用实例简明扼要且极具实用价值,它们覆盖了Android 1.0的所有基本功能和高级功能...

    android文件存储之数据库

    在Android开发中,数据库是一种常用的数据存储方式,用于持久化应用程序的数据。...在"2 android 文件存储之数据库二"这个压缩包文件中,可能包含了更深入的示例代码和讲解,可以帮助你更直观地理解这些概念。

    Android应用开发-SQLite数据库存储.pptx

    在Android应用开发中,SQLite数据库是用于存储应用数据的一个重要组件。SQLite是一个轻量级的、嵌入式的关系型数据库,特别适合于移动设备,因为它不需要独立的服务进程,且占用资源少。以下将详细介绍Android中...

    sqlite学习资源,包括管理器,数据库文件,Android project

    SQLite是一款轻量级的、开源的、嵌入式的SQL数据库引擎,广泛应用于移动设备和桌面应用中,特别是在Android系统中,它是默认的数据存储解决方案。SQLite允许开发者在应用程序中直接存储和检索数据,无需独立的服务器...

    kotlin-for-android-developers-zh.pdf

    - **访问SharedPreferences**:演示如何使用SharedPreferences存储和读取应用设置。 - **泛型preference委托**:介绍如何使用泛型委托简化偏好设置的管理。 #### 测试你的App - **Unit testing**:单元测试是验证...

    android往手机内存和sdcard卡上存储数据

    在Android应用开发中,存储数据是一项基础且重要的任务。这篇内容将详细讲解如何在手机内存以及SDCard(外部存储)上进行数据存储,并提供了一段经过封装的代码,方便开发者直接应用于实际项目。 首先,我们要了解...

    Android群英传笔记-----by ---------刘某人程序员

    在数据存储方面,笔记涵盖了SQLite数据库的使用、SharedPreferences配置文件的读写,以及如何利用ContentProvider进行数据共享。这些知识可以帮助你有效地管理和持久化应用的数据。 此外,笔记还涉及到了网络编程,...

    Android多媒体开发07-数据存储.ppt

    在Android开发中,数据存储是应用功能不可或缺的一部分,它允许应用程序保存用户偏好、数据库记录以及文件等信息。本节将详细讲解四种主要的数据存储方式,包括SharePreference、SQLite、File和Content Provider,...

    Android基础编程-sqlite数据库查询数据.pptx

    在Android开发中,SQLite数据库是应用内存储数据的主要方式,尤其对于小型数据集,它提供了高效、轻量级的解决方案。本课程将深入探讨如何在Android应用中使用SQLite进行数据查询,以“查询‘我身边的榜样’表所有的...

    AndroidResEdit 把安卓应用文件APK汉化的工具

    在Android应用开发中,资源文件(如字符串、图像、布局等)通常存储在res目录下,并以XML格式编译。当需要对应用进行多语言支持时,开发者通常需要创建不同的values文件夹,每个文件夹对应一种语言,如values-en...

    Android SQLite学习工具

    在Android开发中,SQLite是一个非常重要的组成部分,它是一款轻量级的数据库系统,用于存储应用程序中的结构化数据。SQLite数据库引擎被集成到Android系统中,为开发者提供了方便的数据管理方式,无需额外安装服务。...

    Android数据库框架-----ORMLite关联表的使用

    在Android开发中,数据库操作是不可或缺的一部分,而ORMLite是一个轻量级的数据库框架,它简化了在Java应用中,包括Android应用中对数据库的操作。ORMLite提供了丰富的API,使得开发者可以更加专注于业务逻辑,而...

    Android-DBFlow-一个速度极快功能强大而且非常简单的Android数据库ORM库

    通过学习和熟练掌握 DBFlow,你可以轻松地在 Android 应用中实现高效的数据管理。在压缩包文件 agrosner-DBFlow-7176c0d 中,包含了 DBFlow 源码,你可以深入研究其内部实现,以便更好地理解和使用这个库。

    Android代码-SQLite.zip

    SQLite是一款轻量级的数据库,它是Android系统中默认的数据存储解决方案。在Android应用开发中,SQLite数据库被广泛用于持久化应用程序的数据,如用户设置、游戏进度或者任何其他需要长期保存的信息。下面将详细介绍...

    《Android》BMI指数计算器

    - 使用字符串资源文件(strings.xml)来存储应用中的文本,便于多语言支持和代码可读性。 - 如果需要,可以为不同的BMI范围设定颜色资源,以视觉方式区分健康状态。 7. **版本控制**: - 使用Git进行版本控制,...

    命令方式访问Android设备数据库

    在Android系统中,数据库是用于存储应用程序数据的重要组成部分。它通常使用SQLite,一个轻量级、关系型数据库管理系统,能够高效地处理大量的数据。本文将深入探讨如何通过命令行方式来访问Android设备上的数据库,...

    Android zxing二维码扫描 从相册选择二维码识别

    关于权限问题,由于Android 6.0及以上版本引入了运行时权限管理,如果应用需要访问用户的存储空间,你需要在运行时请求WRITE_EXTERNAL_STORAGE权限。你可以使用Android的` ActivityCompat.requestPermissions()`方法...

    Caused by: android.system.ErrnoException: write failed: ENOSPC (

    在Android中,当应用程序试图写入文件或数据到存储设备(如内部存储或SD卡)时,如果目标位置的空间不足以存放这些数据,就会抛出`android.system.ErrnoException`异常,并携带此错误码。 #### 二、常见触发场景 1...

Global site tag (gtag.js) - Google Analytics