1.题记

Android系统中文件的存储方式,以及XML的读取和写入方式基本与Java系统中类似,但由于Android终端系统的存储容量有限,故很多文件的操作都在SD卡上进行。

2.内存文件的存取

文件对数据进行存储,Activity提供了openFileOutput()方法可以用于把数据输出到文件中,具体的实现过程与在J2SE环境中保存数据到文件中是一样的。
public class FileActivity extends Activity {
@Override public void onCreate(Bundle savedInstanceState) {
...
FileOutputStream outStream = this.openFileOutput("android.txt", Context.MODE_PRIVATE);
outStream.write("文件写入".getBytes());
outStream.close();
}
}

openFileOutput()方法的第一参数用于指定文件名称,不能包含路径分隔符“/” ,如果文件不存在,Android 会自动创建它。创建的文件保存在/data/data/<package name>/files目录,如: /data/data/cn.android.action/files/android.txt ,通过点击Eclipse菜单“Window”-“Show View”-“Other”,在对话窗口中展开android文件夹,选择下面的File Explorer视图,然后在File Explorer视图中展开/data/data/<package name>/files目录就可以看到该文件。

openFileOutput()方法的第二参数用于指定操作模式,有四种模式,分别为:
Context.MODE_PRIVATE = 0
Context.MODE_APPEND = 32768
Context.MODE_WORLD_READABLE = 1
Context.MODE_WORLD_WRITEABLE = 2



Context.MODE_PRIVATE:为默认操作模式,代表该文件是私有数据,只能被应用本身访问,在该模式下,写入的内容会覆盖原文件的内容,如果想把新写入的内容追加到原文件中。可以使用Context.MODE_APPEND
Context.MODE_APPEND:模式会检查文件是否存在,存在就往文件追加内容,否则就创建新文件。
Context.MODE_WORLD_READABLE和Context.MODE_WORLD_WRITEABLE用来控制其他应用是否有权限读写该文件。
MODE_WORLD_READABLE:表示当前文件可以被其他应用读取;MODE_WORLD_WRITEABLE:表示当前文件可以被其他应用写入。
如果希望文件被其他应用读和写,可以传入:
openFileOutput("itcast.txt", Context.MODE_WORLD_READABLE + Context.MODE_WORLD_WRITEABLE);

android有一套自己的安全模型,当应用程序(.apk)在安装时系统就会分配给他一个userid,当该应用要去访问其他资源比如文件的时候,就需要userid匹配。默认情况下,任何应用创建的文件,sharedpreferences,数据库都应该是私有的(位于/data/data/<package name>/files),其他程序无法访问。除非在创建时指定了Context.MODE_WORLD_READABLE或者Context.MODE_WORLD_WRITEABLE ,只有这样其他程序才能正确访问。

读取文件内容

如果要打开存放在/data/data/<package name>/files目录应用私有的文件,可以使用Activity提供openFileInput()方法。
FileInputStream inStream = this.getContext().openFileInput("android.txt");
Log.i("FileTest", readInStream(inStream));
readInStream()的方法请看下面备注。
或者直接使用文件的绝对路径:
File file = new File("/data/data/cn.android.action/files/android.txt");
FileInputStream inStream = new FileInputStream(file);
Log.i("FileTest", readInStream(inStream));
--------------------------------------------------------------------------------------------------------
/*备注:
public static String readInStream(FileInputStream inStream){
try {
ByteArrayOutputStream outStream = new ByteArrayOutputStream();
byte[] buffer = new byte[1024];
int length = -1;
while((length = inStream.read(buffer)) != -1 ){
outStream.write(buffer, 0, length);
}
outStream.close();
inStream.close();
return outStream.toString();
} catch (IOException e) {
Log.i("FileTest", e.getMessage());
}
return null;
}

------------------------------------------------------------------------------------------ **/
注意:上面文件路径中的“cn.android.action”为应用所在包,当你在编写代码时应替换为你自己应用使用的包。
Activity还提供了getCacheDir()和getFilesDir()方法:
getCacheDir()方法用于获取/data/data/<package name>/cache目录
getFilesDir()方法用于获取/data/data/<package name>/files目录

3.SD卡的操作

使用Activity的openFileOutput()方法保存文件,文件是存放在手机空间上,一般手机的存储空间不是很大,存放些小文件还行,如果要存放像视频这样的大文件,是不可行的。对于像视频这样的大文件,我们可以把它存放在SDCard。 SDCard是干什么的?你可以把它看作是移动硬盘或U盘。
在模拟器中使用SDCard,你需要先创建一张SDCard卡(当然不是真的SDCard,只是镜像文件)。创建SDCard可以在Eclipse创建模拟器时随同创建.

在程序中访问SDCard,你需要申请访问SDCard的权限。
在AndroidManifest.xml中加入访问SDCard的权限如下:
<!-- 在SDCard中创建与删除文件权限 -->
<uses-permission android:name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS"/>
<!-- 往SDCard写入数据权限 -->
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>

把文件存放在SDCard


要往SDCard存放文件,程序必须先判断手机是否装有SDCard,并且可以进行读写。
注意:访问SDCard必须在AndroidManifest.xml中加入访问SDCard的权限
if(Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)){
File sdCardDir = Environment.getExternalStorageDirectory();//获取SDCard目录
File saveFile = new File(sdCardDir, “itcast.txt”);
FileOutputStream outStream = new FileOutputStream(saveFile);
outStream.write("中国".getBytes());
outStream.close();
}
Environment.getExternalStorageState()方法用于获取SDCard的状态,如果手机装有SDCard,并且可以进行读写,那么方法返回的状态等于Environment.MEDIA_MOUNTED。
Environment.getExternalStorageDirectory()方法用于获取SDCard的目录,当然要获取SDCard的目录,你也可以这样写:
File sdCardDir = new File("/mnt/sdcard"); //获取SDCard目录
File saveFile = new File(sdCardDir, "itcast.txt");
//上面两句代码可以合成一句: File saveFile = new File("/mnt/sdcard/itcast.txt");
FileOutputStream outStream = new FileOutputStream(saveFile);
outStream.write("SD卡存储测试".getBytes());
outStream.close();

4.XML解析

在Android平台上可以使用Simple API for XML(SAX) 、 Document Object Model(DOM)和Android附带的pull解析器解析XML文件。

4.1使用SAX解析XML文件

SAX是一个解析速度快并且占用内存少的xml解析器,非常适合用于Android等移动设备。 SAX解析XML文件采用的是事件驱动,也就是说,它并不需要解析完整个文档,在按内容顺序解析文档的过程中,SAX会判断当前读到的字符是否合法XML语法中的某部分,如果符合就会触发事件。所谓事件,其实就是一些回调(callback)方法,这些方法(事件)定义在ContentHandler接口。下面是一些ContentHandler接口常用的方法:
startDocument()
当遇到文档的开头的时候,调用这个方法,可以在其中做一些预处理的工作。
endDocument()
和上面的方法相对应,当文档结束的时候,调用这个方法,可以在其中做一些善后的工作。
startElement(String namespaceURI, String localName, String qName, Attributes atts)
当读到一个开始标签的时候,会触发这个方法。namespaceURI就是命名空间,localName是不带命名空间前缀的标签名,qName是带命名空间前缀的标签名。通过atts可以得到所有的属性名和相应的值。要注意的是SAX中一个重要的特点就是它的流式处理,当遇到一个标签的时候,它并不会纪录下以前所碰到的标签,也就是说,在startElement()方法中,所有你所知道的信息,就是标签的名字和属性,至于标签的嵌套结构,上层标签的名字,是否有子元属等等其它与结构相关的信息,都是不得而知的,都需要你的程序来完成。这使得SAX在编程处理上没有DOM来得那么方便。
endElement(String uri, String localName, String name)
这个方法和上面的方法相对应,在遇到结束标签的时候,调用这个方法。
characters(char[] ch, int start, int length)
这个方法用来处理在XML文件中读到的内容,第一个参数为文件的字符串内容,后面两个参数是读到的字符串在这个数组中的起始位置和长度,使用new String(ch,start,length)就可以获取内容。

只要为SAX提供实现ContentHandler接口的类,那么该类就可以得到通知事件(实际上就是SAX调用了该类中的回调方法)。因为ContentHandler是一个接口,在使用的时候可能会有些不方便,因此,SAX还为其制定了一个Helper类:DefaultHandler,它实现了ContentHandler接口,但是其所有的方法体都为空,在实现的时候,你只需要继承这个类,然后重写相应的方法即可。

SAX 支持已内置到JDK1.5中,无需添加任何的jar文件。关于XMLContentHandler的代码实现:

Java代码
  1. importjava.util.ArrayList;
  2. importjava.util.List;
  3. importorg.xml.sax.Attributes;
  4. importorg.xml.sax.SAXException;
  5. importorg.xml.sax.helpers.DefaultHandler;
  6. importcom.sulang.android.xml.vo.Person;
  7. /*
  8. *@author七里香的悔恨,2011-3-18
  9. *XMLContentHandler.java
  10. *Blog:[url]http://bigboy.iteye.com/[/url]
  11. */
  12. publicclassXMLContentHandlerextendsDefaultHandler{
  13. privateList<Person>persons=null;
  14. privatePersoncurrentPerson;
  15. privateStringtagName=null;//当前解析的元素标签
  16. publicList<Person>getPersons(){
  17. returnpersons;
  18. }
  19. /*
  20. *接收文档的开始的通知。
  21. */
  22. @Override
  23. publicvoidstartDocument()throwsSAXException{
  24. persons=newArrayList<Person>();
  25. }
  26. /*
  27. *接收字符数据的通知。
  28. */
  29. @Override
  30. publicvoidcharacters(char[]ch,intstart,intlength)
  31. throwsSAXException{
  32. if(tagName!=null){
  33. Stringdata=newString(ch,start,length);
  34. if(tagName.equals("name")){
  35. this.currentPerson.setName(data);
  36. }elseif(tagName.equals("age")){
  37. this.currentPerson.setAge(Short.parseShort(data));
  38. }
  39. }
  40. }
  41. /*
  42. *接收元素开始的通知。参数意义如下:namespaceURI:元素的命名空间localName:元素的本地名称(不带前缀)qName
  43. *:元素的限定名(带前缀)atts:元素的属性集合
  44. */
  45. @Override
  46. publicvoidstartElement(StringnamespaceURI,StringlocalName,
  47. StringqName,Attributesatts)throwsSAXException{
  48. if(localName.equals("person")){
  49. currentPerson=newPerson();
  50. currentPerson.setId(Integer.parseInt(atts.getValue("id")));
  51. }
  52. this.tagName=localName;
  53. }
  54. /*
  55. *接收文档的结尾的通知。参数意义如下:uri:元素的命名空间localName:元素的本地名称(不带前缀)name
  56. *:元素的限定名(带前缀)
  57. */
  58. @Override
  59. publicvoidendElement(Stringuri,StringlocalName,Stringname)
  60. throwsSAXException{
  61. if(localName.equals("person")){
  62. persons.add(currentPerson);
  63. currentPerson=null;
  64. }
  65. this.tagName=null;
  66. }
  67. }
import java.util.ArrayList;import java.util.List;import org.xml.sax.Attributes;import org.xml.sax.SAXException;import org.xml.sax.helpers.DefaultHandler;import com.sulang.android.xml.vo.Person;/* *@author 七里香的悔恨,2011-3-18 *XMLContentHandler.java *Blog:[url]http://bigboy.iteye.com/[/url] */public class XMLContentHandler extends DefaultHandler {private List<Person> persons = null;private Person currentPerson;private String tagName = null;// 当前解析的元素标签public List<Person> getPersons() {return persons;}/* * 接收文档的开始的通知。 */@Overridepublic void startDocument() throws SAXException {persons = new ArrayList<Person>();}/* * 接收字符数据的通知。 */@Overridepublic void characters(char[] ch, int start, int length)throws SAXException {if (tagName != null) {String data = new String(ch, start, length);if (tagName.equals("name")) {this.currentPerson.setName(data);} else if (tagName.equals("age")) {this.currentPerson.setAge(Short.parseShort(data));}}}/* * 接收元素开始的通知。 参数意义如下: namespaceURI:元素的命名空间 localName :元素的本地名称(不带前缀) qName * :元素的限定名(带前缀) atts :元素的属性集合 */@Overridepublic void startElement(String namespaceURI, String localName,String qName, Attributes atts) throws SAXException {if (localName.equals("person")) {currentPerson = new Person();currentPerson.setId(Integer.parseInt(atts.getValue("id")));}this.tagName = localName;}/* * 接收文档的结尾的通知。 参数意义如下: uri :元素的命名空间 localName :元素的本地名称(不带前缀) name * :元素的限定名(带前缀) */@Overridepublic void endElement(String uri, String localName, String name)throws SAXException {if (localName.equals("person")) {persons.add(currentPerson);currentPerson = null;}this.tagName = null;}}

4.2使用DOM解析XML文件

除了使用 SAX可以解析XML文件,大家也可以使用熟悉的DOM来解析XML文件。 DOM解析XML文件时,会将XML文件的所有内容以文档树方式存放在内存中,然后允许您使用DOM API遍历XML树、检索所需的数据。使用DOM操作XML的代码看起来是比较直观的,并且在编码方面比基于SAX的实现更加简单。但是,因为DOM需要将XML文件的所有内容以文档树方式存放在内存中,所以内存的消耗比较大,特别对于运行Android的移动设备来说,因为设备的资源比较宝贵,所以建议还是采用SAX来解析XML文件,当然,如果XML文件的内容比较小采用DOM也是可行的。

代码示例:

Java代码
  1. publicstaticList<Person>readXMLByDOM(InputStreaminStream){
  2. List<Person>persons=newArrayList<Person>();
  3. DocumentBuilderFactoryfactory=DocumentBuilderFactory.newInstance();
  4. try{
  5. DocumentBuilderbuilder=factory.newDocumentBuilder();
  6. Documentdoc=builder.parse(inStream);
  7. doc.normalize();//去掉不必要的空白
  8. NodeListnodeList=doc.getElementsByTagName("person");
  9. for(inti=0;i<nodeList.getLength();i++){
  10. ElementpersonNode=(Element)nodeList.item(i);
  11. Personperson=newPerson();
  12. //获取person节点的id属性值
  13. person.setId(newInteger(personNode.getAttribute("id")));
  14. //获取person节点下的所有子节点(标签之间的空白节点和name/age元素)
  15. NodeListchildsNodes=personNode.getChildNodes();
  16. for(intj=0;j<childsNodes.getLength();j++){
  17. Nodenode=(Node)childsNodes.item(j);//判断是否为元素类型
  18. if(node.getNodeType()==Node.ELEMENT_NODE){
  19. ElementchildNode=(Element)node;
  20. //判断是否name元素
  21. if("name".equals(childNode.getNodeName())){
  22. //获取name元素下Text节点,然后从Text节点获取数据
  23. person.setName(childNode.getFirstChild()
  24. .getNodeValue());
  25. }elseif("age".equals(childNode.getNodeName())){
  26. person.setAge(newShort(childNode.getFirstChild()
  27. .getNodeValue()));
  28. }
  29. }
  30. }
  31. persons.add(person);
  32. inStream.close();
  33. }
  34. }catch(Exceptione){
  35. e.printStackTrace();
  36. }
  37. returnpersons;
  38. }
public static List<Person> readXMLByDOM(InputStream inStream) {List<Person> persons = new ArrayList<Person>();DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();try {DocumentBuilder builder = factory.newDocumentBuilder();Document doc = builder.parse(inStream);doc.normalize();// 去掉不必要的空白NodeList nodeList = doc.getElementsByTagName("person");for (int i = 0; i < nodeList.getLength(); i++) {Element personNode = (Element) nodeList.item(i);Person person = new Person();// 获取person节点的id属性值person.setId(new Integer(personNode.getAttribute("id")));// 获取person节点下的所有子节点(标签之间的空白节点和name/age元素)NodeList childsNodes = personNode.getChildNodes();for (int j = 0; j < childsNodes.getLength(); j++) {Node node = (Node) childsNodes.item(j); // 判断是否为元素类型if (node.getNodeType() == Node.ELEMENT_NODE) {Element childNode = (Element) node;// 判断是否name元素if ("name".equals(childNode.getNodeName())) {// 获取name元素下Text节点,然后从Text节点获取数据person.setName(childNode.getFirstChild().getNodeValue());} else if ("age".equals(childNode.getNodeName())) {person.setAge(new Short(childNode.getFirstChild().getNodeValue()));}}}persons.add(person);inStream.close();}} catch (Exception e) {e.printStackTrace();}return persons;}

4.3使用PULL方式解析XML文件

除了可以使用 SAX或DOM解析XML文件之外,大家也可以使用Android内置的Pull解析器解析XML文件。 Pull解析器是一个开源的java项目,既可以用于android,也可以用于JavaEE。如果用在javaEE需要把其jar文件放入类路径中,因为Android已经集成进了Pull解析器,所以无需添加任何jar文件。android系统本身使用到的各种xml文件,其内部也是采用Pull解析器进行解析的。 Pull解析器的运行方式与 SAX 解析器相似。它提供了类似的事件,如:开始元素和结束元素事件,使用parser.next()可以进入下一个元素并触发相应事件。跟SAX不同的是, Pull解析器产生的事件是一个数字,而非方法,因此可以使用一个switch对感兴趣的事件进行处理。当元素开始解析时,调用parser.nextText()方法可以获取下一个Text类型节点的值。

示例代码:

Java代码
  1. publicstaticList<Person>readXMLByPull(InputStreaminStream){
  2. XmlPullParserparser=Xml.newPullParser();
  3. try{
  4. parser.setInput(inStream,"UTF-8");
  5. inteventType=parser.getEventType();
  6. PersoncurrentPerson=null;
  7. List<Person>persons=null;
  8. while(eventType!=XmlPullParser.END_DOCUMENT){
  9. switch(eventType){
  10. caseXmlPullParser.START_DOCUMENT://文档开始事件,可以进行数据初始化处理
  11. persons=newArrayList<Person>();
  12. break;
  13. caseXmlPullParser.START_TAG://开始元素事件
  14. Stringname=parser.getName();
  15. if(name.equalsIgnoreCase("person")){
  16. currentPerson=newPerson();
  17. currentPerson.setId(newInteger(parser
  18. .getAttributeValue(null,"id")));
  19. }elseif(currentPerson!=null){
  20. if(name.equalsIgnoreCase("name")){
  21. currentPerson.setName(parser.nextText());//如果后面是Text节点,即返回它的值
  22. }elseif(name.equalsIgnoreCase("age")){
  23. currentPerson.setAge(newShort(parser.nextText()));
  24. }
  25. }
  26. break;
  27. caseXmlPullParser.END_TAG://结束元素事件
  28. if(parser.getName().equalsIgnoreCase("person")
  29. &&currentPerson!=null){
  30. persons.add(currentPerson);
  31. currentPerson=null;
  32. }
  33. break;
  34. }
  35. eventType=parser.next();
  36. }
  37. inStream.close();
  38. returnpersons;
  39. }catch(Exceptione){
  40. e.printStackTrace();
  41. }
  42. returnnull;
  43. }
public static List<Person> readXMLByPull(InputStream inStream) {XmlPullParser parser = Xml.newPullParser();try {parser.setInput(inStream, "UTF-8");int eventType = parser.getEventType();Person currentPerson = null;List<Person> persons = null;while (eventType != XmlPullParser.END_DOCUMENT) {switch (eventType) {case XmlPullParser.START_DOCUMENT:// 文档开始事件,可以进行数据初始化处理persons = new ArrayList<Person>();break;case XmlPullParser.START_TAG:// 开始元素事件String name = parser.getName();if (name.equalsIgnoreCase("person")) {currentPerson = new Person();currentPerson.setId(new Integer(parser.getAttributeValue(null, "id")));} else if (currentPerson != null) {if (name.equalsIgnoreCase("name")) {currentPerson.setName(parser.nextText());// 如果后面是Text节点,即返回它的值} else if (name.equalsIgnoreCase("age")) {currentPerson.setAge(new Short(parser.nextText()));}}break;case XmlPullParser.END_TAG:// 结束元素事件if (parser.getName().equalsIgnoreCase("person")&& currentPerson != null) {persons.add(currentPerson);currentPerson = null;}break;}eventType = parser.next();}inStream.close();return persons;} catch (Exception e) {e.printStackTrace();}return null;}

用Pull解析器生成XML文件

有些时候,我们需要生成一个XML文件,生成XML文件的方法有很多,如:可以只使用一个StringBuilder组拼XML内容,然后把内容写入到文件中;或者使用DOM API生成XML文件,或者也可以使用pull解析器生成XML文件,这里推荐大家使用Pull解析器。

示例代码:

Java代码
  1. publicstaticStringwriteXMLByPull(List<Person>persons,Writerwriter){
  2. XmlSerializerserializer=Xml.newSerializer();
  3. try{
  4. serializer.setOutput(writer);
  5. serializer.startDocument("UTF-8",true);
  6. //第一个参数为命名空间,如果不使用命名空间,可以设置为null
  7. serializer.startTag("","persons");
  8. for(Personperson:persons){
  9. serializer.startTag("","person");
  10. serializer.attribute("","id",person.getId().toString());
  11. serializer.startTag("","name");
  12. serializer.text(person.getName());
  13. serializer.endTag("","name");
  14. serializer.startTag("","age");
  15. serializer.text(person.getAge().toString());
  16. serializer.endTag("","age");
  17. serializer.endTag("","person");
  18. }
  19. serializer.endTag("","persons");
  20. serializer.endDocument();
  21. returnwriter.toString();
  22. }catch(Exceptione){
  23. e.printStackTrace();
  24. }
  25. returnnull;
  26. }
public static String writeXMLByPull(List<Person> persons, Writer writer) {XmlSerializer serializer = Xml.newSerializer();try {serializer.setOutput(writer);serializer.startDocument("UTF-8", true);// 第一个参数为命名空间,如果不使用命名空间,可以设置为nullserializer.startTag("", "persons");for (Person person : persons) {serializer.startTag("", "person");serializer.attribute("", "id", person.getId().toString());serializer.startTag("", "name");serializer.text(person.getName());serializer.endTag("", "name");serializer.startTag("", "age");serializer.text(person.getAge().toString());serializer.endTag("", "age");serializer.endTag("", "person");}serializer.endTag("", "persons");serializer.endDocument();return writer.toString();} catch (Exception e) {e.printStackTrace();}return null;}

5.简单实例

实例简单实现了从SD卡上读取XML,解析XML后,将解析出来的联系人用ListView显示出来。主要代码如下:

MainActivity.java

Java代码
  1. packagecom.sulang.android.xml;
  2. importjava.io.File;
  3. importjava.io.FileInputStream;
  4. importjava.io.FileNotFoundException;
  5. importjava.util.ArrayList;
  6. importjava.util.HashMap;
  7. importjava.util.List;
  8. importjava.util.Map;
  9. importcom.sulang.android.xml.vo.Person;
  10. importandroid.app.Activity;
  11. importandroid.graphics.Color;
  12. importandroid.os.Bundle;
  13. importandroid.os.Environment;
  14. importandroid.widget.LinearLayout;
  15. importandroid.widget.ListAdapter;
  16. importandroid.widget.ListView;
  17. importandroid.widget.SimpleAdapter;
  18. publicclassMainActivityextendsActivity{
  19. /**Calledwhentheactivityisfirstcreated.*/
  20. @Override
  21. publicvoidonCreate(BundlesavedInstanceState){
  22. super.onCreate(savedInstanceState);
  23. //setContentView(R.layout.main);
  24. LinearLayoutlinearLayout=newLinearLayout(this);
  25. ListViewlistView=newListView(this);
  26. linearLayout.setOrientation(LinearLayout.VERTICAL);
  27. linearLayout.setBackgroundColor(android.graphics.Color.BLACK);
  28. LinearLayout.LayoutParamsparam=newLinearLayout.LayoutParams(LinearLayout.LayoutParams.FILL_PARENT,LinearLayout.LayoutParams.WRAP_CONTENT);
  29. listView.setBackgroundColor(Color.BLACK);
  30. linearLayout.addView(listView,param);
  31. setContentView(linearLayout);
  32. ListAdapteradapter=newSimpleAdapter(this,getData(),R.layout.mylist,newString[]{"id","name","age"},newint[]{
  33. R.id.id,R.id.name,R.id.age
  34. });
  35. listView.setAdapter(adapter);
  36. }
  37. privateList<Map<String,Object>>getData()
  38. {
  39. List<Map<String,Object>>data=newArrayList<Map<String,Object>>();
  40. if(Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)){
  41. //FilesdCardDir=newFile("/mnt/sdcard");//获取SDCard目录
  42. FilesdCardDir=Environment.getExternalStorageDirectory();//获取SDCard目录
  43. FiledataFile=newFile(sdCardDir,"china.xml");
  44. try{
  45. FileInputStreaminputStream=newFileInputStream(dataFile);
  46. List<Person>persons=XMLReader.readXMLByDOM(inputStream);
  47. for(Personperson:persons)
  48. {
  49. Map<String,Object>map=newHashMap<String,Object>();
  50. map.put("id",person.getId());
  51. map.put("age",person.getAge());
  52. map.put("name",person.getName());
  53. data.add(map);
  54. }
  55. }catch(FileNotFoundExceptione){
  56. //TODOAuto-generatedcatchblock
  57. e.printStackTrace();
  58. }
  59. }
  60. returndata;
  61. }
  62. }
package com.sulang.android.xml;import java.io.File;import java.io.FileInputStream;import java.io.FileNotFoundException;import java.util.ArrayList;import java.util.HashMap;import java.util.List;import java.util.Map;import com.sulang.android.xml.vo.Person;import android.app.Activity;import android.graphics.Color;import android.os.Bundle;import android.os.Environment;import android.widget.LinearLayout;import android.widget.ListAdapter;import android.widget.ListView;import android.widget.SimpleAdapter;public class MainActivity extends Activity {    /** Called when the activity is first created. */    @Override    public void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        //setContentView(R.layout.main);        LinearLayout linearLayout=new LinearLayout(this);        ListView listView=new ListView(this);        linearLayout.setOrientation(LinearLayout.VERTICAL);        linearLayout.setBackgroundColor(android.graphics.Color.BLACK);        LinearLayout.LayoutParams param=new LinearLayout.LayoutParams(LinearLayout.LayoutParams.FILL_PARENT,LinearLayout.LayoutParams.WRAP_CONTENT);        listView.setBackgroundColor(Color.BLACK);        linearLayout.addView(listView,param);        setContentView(linearLayout);        ListAdapter adapter=new SimpleAdapter(this,getData(),R.layout.mylist,new String[]{"id","name","age"},new int[]{        R.id.id,R.id.name,R.id.age        });        listView.setAdapter(adapter);    }    private List<Map<String, Object>> getData()    {    List<Map<String, Object>> data = new ArrayList<Map<String, Object>>();        if(Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)){     //File sdCardDir = new File("/mnt/sdcard"); //获取SDCard目录    File sdCardDir = Environment.getExternalStorageDirectory();//获取SDCard目录    File dataFile = new File(sdCardDir, "china.xml");     try {FileInputStream inputStream = new FileInputStream(dataFile);List<Person> persons = XMLReader.readXMLByDOM(inputStream);for(Person person:persons){Map<String, Object> map = new HashMap<String, Object>();  map.put("id", person.getId());map.put("age", person.getAge());map.put("name", person.getName());data.add(map);}} catch (FileNotFoundException e) {// TODO Auto-generated catch blocke.printStackTrace();}    }    return data;    }}

XMLReader.java

Java代码
  1. packagecom.sulang.android.xml;
  2. importjava.io.File;
  3. importjava.io.FileInputStream;
  4. importjava.io.FileNotFoundException;
  5. importjava.io.IOException;
  6. importjava.io.InputStream;
  7. importjava.io.Writer;
  8. importjava.util.ArrayList;
  9. importjava.util.List;
  10. importjavax.xml.parsers.DocumentBuilder;
  11. importjavax.xml.parsers.DocumentBuilderFactory;
  12. importjavax.xml.parsers.SAXParser;
  13. importjavax.xml.parsers.SAXParserFactory;
  14. importorg.w3c.dom.Document;
  15. importorg.w3c.dom.Element;
  16. importorg.w3c.dom.Node;
  17. importorg.w3c.dom.NodeList;
  18. importorg.xmlpull.v1.XmlPullParser;
  19. importorg.xmlpull.v1.XmlSerializer;
  20. importandroid.util.Xml;
  21. importcom.sulang.android.xml.vo.Person;
  22. /*
  23. *@author七里香的悔恨,2011-3-18
  24. *XMLReader.java
  25. *Blog:[url]http://bigboy.iteye.com/[/url]
  26. */
  27. publicclassXMLReader{
  28. publicstaticList<Person>readXMLBySAX(InputStreaminStream){
  29. try{
  30. SAXParserFactoryspf=SAXParserFactory.newInstance();
  31. SAXParsersaxParser=spf.newSAXParser();//创建解析器
  32. //设置解析器的相关特性,http://xml.org/sax/features/namespaces=true
  33. //表示开启命名空间特性
  34. //saxParser.setProperty("http://xml.org/sax/features/namespaces",true);
  35. XMLContentHandlerhandler=newXMLContentHandler();
  36. saxParser.parse(inStream,handler);
  37. inStream.close();
  38. returnhandler.getPersons();
  39. }catch(Exceptione){
  40. e.printStackTrace();
  41. }
  42. returnnull;
  43. }
  44. publicstaticList<Person>readXMLByDOM(InputStreaminStream){
  45. List<Person>persons=newArrayList<Person>();
  46. DocumentBuilderFactoryfactory=DocumentBuilderFactory.newInstance();
  47. try{
  48. DocumentBuilderbuilder=factory.newDocumentBuilder();
  49. Documentdoc=builder.parse(inStream);
  50. doc.normalize();//去掉不必要的空白
  51. NodeListnodeList=doc.getElementsByTagName("person");
  52. for(inti=0;i<nodeList.getLength();i++){
  53. ElementpersonNode=(Element)nodeList.item(i);
  54. Personperson=newPerson();
  55. //获取person节点的id属性值
  56. person.setId(newInteger(personNode.getAttribute("id")));
  57. //获取person节点下的所有子节点(标签之间的空白节点和name/age元素)
  58. NodeListchildsNodes=personNode.getChildNodes();
  59. for(intj=0;j<childsNodes.getLength();j++){
  60. Nodenode=(Node)childsNodes.item(j);//判断是否为元素类型
  61. if(node.getNodeType()==Node.ELEMENT_NODE){
  62. ElementchildNode=(Element)node;
  63. //判断是否name元素
  64. if("name".equals(childNode.getNodeName())){
  65. //获取name元素下Text节点,然后从Text节点获取数据
  66. person.setName(childNode.getFirstChild()
  67. .getNodeValue());
  68. }elseif("age".equals(childNode.getNodeName())){
  69. person.setAge(newShort(childNode.getFirstChild()
  70. .getNodeValue()));
  71. }
  72. }
  73. }
  74. persons.add(person);
  75. inStream.close();
  76. }
  77. }catch(Exceptione){
  78. e.printStackTrace();
  79. }
  80. returnpersons;
  81. }
  82. publicstaticList<Person>readXMLByPull(InputStreaminStream){
  83. XmlPullParserparser=Xml.newPullParser();
  84. try{
  85. parser.setInput(inStream,"UTF-8");
  86. inteventType=parser.getEventType();
  87. PersoncurrentPerson=null;
  88. List<Person>persons=null;
  89. while(eventType!=XmlPullParser.END_DOCUMENT){
  90. switch(eventType){
  91. caseXmlPullParser.START_DOCUMENT://文档开始事件,可以进行数据初始化处理
  92. persons=newArrayList<Person>();
  93. break;
  94. caseXmlPullParser.START_TAG://开始元素事件
  95. Stringname=parser.getName();
  96. if(name.equalsIgnoreCase("person")){
  97. currentPerson=newPerson();
  98. currentPerson.setId(newInteger(parser
  99. .getAttributeValue(null,"id")));
  100. }elseif(currentPerson!=null){
  101. if(name.equalsIgnoreCase("name")){
  102. currentPerson.setName(parser.nextText());//如果后面是Text节点,即返回它的值
  103. }elseif(name.equalsIgnoreCase("age")){
  104. currentPerson.setAge(newShort(parser.nextText()));
  105. }
  106. }
  107. break;
  108. caseXmlPullParser.END_TAG://结束元素事件
  109. if(parser.getName().equalsIgnoreCase("person")
  110. &&currentPerson!=null){
  111. persons.add(currentPerson);
  112. currentPerson=null;
  113. }
  114. break;
  115. }
  116. eventType=parser.next();
  117. }
  118. inStream.close();
  119. returnpersons;
  120. }catch(Exceptione){
  121. e.printStackTrace();
  122. }
  123. returnnull;
  124. }
  125. publicstaticStringwriteXMLByPull(List<Person>persons,Writerwriter){
  126. XmlSerializerserializer=Xml.newSerializer();
  127. try{
  128. serializer.setOutput(writer);
  129. serializer.startDocument("UTF-8",true);
  130. //第一个参数为命名空间,如果不使用命名空间,可以设置为null
  131. serializer.startTag("","persons");
  132. for(Personperson:persons){
  133. serializer.startTag("","person");
  134. serializer.attribute("","id",person.getId().toString());
  135. serializer.startTag("","name");
  136. serializer.text(person.getName());
  137. serializer.endTag("","name");
  138. serializer.startTag("","age");
  139. serializer.text(person.getAge().toString());
  140. serializer.endTag("","age");
  141. serializer.endTag("","person");
  142. }
  143. serializer.endTag("","persons");
  144. serializer.endDocument();
  145. returnwriter.toString();
  146. }catch(Exceptione){
  147. e.printStackTrace();
  148. }
  149. returnnull;
  150. }
  151. /**
  152. *@paramargs
  153. */
  154. publicstaticvoidmain(String[]args){
  155. InputStreaminputStream;
  156. try{
  157. inputStream=newFileInputStream(newFile("china.xml"));
  158. List<Person>list=XMLReader.readXMLByDOM(inputStream);
  159. System.out.println(list.size());
  160. }catch(FileNotFoundExceptione){
  161. //TODOAuto-generatedcatchblock
  162. e.printStackTrace();
  163. }
  164. }
  165. }
package com.sulang.android.xml;import java.io.File;import java.io.FileInputStream;import java.io.FileNotFoundException;import java.io.IOException;import java.io.InputStream;import java.io.Writer;import java.util.ArrayList;import java.util.List;import javax.xml.parsers.DocumentBuilder;import javax.xml.parsers.DocumentBuilderFactory;import javax.xml.parsers.SAXParser;import javax.xml.parsers.SAXParserFactory;import org.w3c.dom.Document;import org.w3c.dom.Element;import org.w3c.dom.Node;import org.w3c.dom.NodeList;import org.xmlpull.v1.XmlPullParser;import org.xmlpull.v1.XmlSerializer;import android.util.Xml;import com.sulang.android.xml.vo.Person;/* *@author 七里香的悔恨,2011-3-18 *XMLReader.java *Blog:[url]http://bigboy.iteye.com/[/url] */public class XMLReader {public static List<Person> readXMLBySAX(InputStream inStream) {try {SAXParserFactory spf = SAXParserFactory.newInstance();SAXParser saxParser = spf.newSAXParser(); // 创建解析器// 设置解析器的相关特性,http://xml.org/sax/features/namespaces = true// 表示开启命名空间特性// saxParser.setProperty("http://xml.org/sax/features/namespaces",true);XMLContentHandler handler = new XMLContentHandler();saxParser.parse(inStream, handler);inStream.close();return handler.getPersons();} catch (Exception e) {e.printStackTrace();}return null;}public static List<Person> readXMLByDOM(InputStream inStream) {List<Person> persons = new ArrayList<Person>();DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();try {DocumentBuilder builder = factory.newDocumentBuilder();Document doc = builder.parse(inStream);doc.normalize();// 去掉不必要的空白NodeList nodeList = doc.getElementsByTagName("person");for (int i = 0; i < nodeList.getLength(); i++) {Element personNode = (Element) nodeList.item(i);Person person = new Person();// 获取person节点的id属性值person.setId(new Integer(personNode.getAttribute("id")));// 获取person节点下的所有子节点(标签之间的空白节点和name/age元素)NodeList childsNodes = personNode.getChildNodes();for (int j = 0; j < childsNodes.getLength(); j++) {Node node = (Node) childsNodes.item(j); // 判断是否为元素类型if (node.getNodeType() == Node.ELEMENT_NODE) {Element childNode = (Element) node;// 判断是否name元素if ("name".equals(childNode.getNodeName())) {// 获取name元素下Text节点,然后从Text节点获取数据person.setName(childNode.getFirstChild().getNodeValue());} else if ("age".equals(childNode.getNodeName())) {person.setAge(new Short(childNode.getFirstChild().getNodeValue()));}}}persons.add(person);inStream.close();}} catch (Exception e) {e.printStackTrace();}return persons;}public static List<Person> readXMLByPull(InputStream inStream) {XmlPullParser parser = Xml.newPullParser();try {parser.setInput(inStream, "UTF-8");int eventType = parser.getEventType();Person currentPerson = null;List<Person> persons = null;while (eventType != XmlPullParser.END_DOCUMENT) {switch (eventType) {case XmlPullParser.START_DOCUMENT:// 文档开始事件,可以进行数据初始化处理persons = new ArrayList<Person>();break;case XmlPullParser.START_TAG:// 开始元素事件String name = parser.getName();if (name.equalsIgnoreCase("person")) {currentPerson = new Person();currentPerson.setId(new Integer(parser.getAttributeValue(null, "id")));} else if (currentPerson != null) {if (name.equalsIgnoreCase("name")) {currentPerson.setName(parser.nextText());// 如果后面是Text节点,即返回它的值} else if (name.equalsIgnoreCase("age")) {currentPerson.setAge(new Short(parser.nextText()));}}break;case XmlPullParser.END_TAG:// 结束元素事件if (parser.getName().equalsIgnoreCase("person")&& currentPerson != null) {persons.add(currentPerson);currentPerson = null;}break;}eventType = parser.next();}inStream.close();return persons;} catch (Exception e) {e.printStackTrace();}return null;}public static String writeXMLByPull(List<Person> persons, Writer writer) {XmlSerializer serializer = Xml.newSerializer();try {serializer.setOutput(writer);serializer.startDocument("UTF-8", true);// 第一个参数为命名空间,如果不使用命名空间,可以设置为nullserializer.startTag("", "persons");for (Person person : persons) {serializer.startTag("", "person");serializer.attribute("", "id", person.getId().toString());serializer.startTag("", "name");serializer.text(person.getName());serializer.endTag("", "name");serializer.startTag("", "age");serializer.text(person.getAge().toString());serializer.endTag("", "age");serializer.endTag("", "person");}serializer.endTag("", "persons");serializer.endDocument();return writer.toString();} catch (Exception e) {e.printStackTrace();}return null;}/** * @param args */public static void main(String[] args) {InputStream inputStream;try {inputStream = new FileInputStream(new File("china.xml"));List<Person> list = XMLReader.readXMLByDOM(inputStream);System.out.println(list.size());} catch (FileNotFoundException e) {// TODO Auto-generated catch blocke.printStackTrace();}}}

person.xml

Xml代码
  1. <?xmlversion="1.0"encoding="UTF-8"?>
  2. <persons>
  3. <personid="23">
  4. <name>liming</name>
  5. <age>30</age>
  6. </person>
  7. <personid="20">
  8. <name>zhangxiaoxiao</name>
  9. <age>25</age>
  10. </person>
  11. </persons>
<?xml version="1.0" encoding="UTF-8"?><persons><person id="23"><name>liming</name><age>30</age></person><person id="20"><name>zhangxiaoxiao</name><age>25</age></person></persons> 

运行效果:

源代码:

  • 大小: 3.7 KB
  • XMLDemo.rar (60.4 KB)
  • 下载次数: 13
  • 查看图片附件

更多相关文章

  1. Android(安卓)数据存储---File内部存储
  2. Android程序开发基础之——页面布局
  3. 在Android(安卓)Studio 2.2上集成OpenCV For Android(安卓)SDK
  4. android手机QQ尾巴修改(QQ for Pad)
  5. Android(安卓)Retrofit 2.0(一)初次见面请多多关照
  6. 全志A10平板上的ubuntu终极安装版,支持HDMI和平板本机LCD,全新内核
  7. Android(安卓)模仿360二维码扫描功能
  8. android 非系统APP访问字符设备
  9. Android(安卓)查看SharedPreferences中的数据

随机推荐

  1. android dialog 显示时弹出输入法
  2. android SlidingDrawer
  3. android facebook authorize 时禁止调用f
  4. android使用javamail 发送邮件遇到的问题
  5. Android(安卓)studio图片ERROR: 9-patch
  6. Android:在WebView中获取网页源码
  7. android 按钮按下时改变字体颜色
  8. android 源码下载与编译(ubuntu11.04)
  9. Android(安卓)本地文件管理类
  10. Android(安卓)手势滑动切换activity