【Android】学习札记第7章之IO流三及XML初步
上一节介绍了字节流的使用,这一节会继续深入介绍字符流的使用,会涉及到读写过程中的字符编码转换,和对象序列化。当我们正在玩android编写的游戏时,突然来了电话,这时就可能需要对象序列化来保存状态,当继续玩游戏时再恢复数据。
在网络上传输数据用的最多的语言就是XML了,它是结构化语言,语法严格,语义表达清楚,这一节就会初步了解XML的基本语法。
工具/原料
JDK、eclipse、android SDK、ADT
一、IO
1、PrintStream
①任何类型数据转成字符串输出
②创建对象
PrintStream p=new PrintStream(相接的流)
PrintStream p=new PrintStream(文件)
PrintStream p=new PrintStream(文件,字符集)
③方法
print(97):39 37
println(97):39 37 0D 0A->97\r\n
2、编码
⑴字符编码Encoding、字符集Charset
①单字节字符:
ASC-Ⅱ:0-127个字符(包含英文、标点字符)
西欧字符(ISO-8859-1或Latin-1):包含159-255个字符
注:(127,159)字符包含控制字符
②双字节字符:
国标GB2312:包含7K多个中文,不包含一些姓、不常见的字“喆、镕”,用字符“?”代替。
GBK:包含20902个中文
③Unicode:统一码、万国码,包含70万多个字符。
常用字符:双字节
生僻字符:三个或三个以上的字节
注:java的char类型属于Unicode编码。
Unicode传输格式:
UTF-8:对英文占1字节,对某些字符占2字节,对中文占3字节。
UTF-16Be:
UTF-16Le:每个字节与UTF-16Be相反
⑵编码转换
①Unicode->其他编码
String s="abc中文";
byte[] a=s.getBytes();//Unicode->操作系统默认编码(android:utf-8,window:gbk)
byte[] a=s.getBytes("UTF-8");//Unicode->UTF-8
②其他编码->Unicode
String s=new String(a);//操作系统默认编码->Unicode
String s=new String(a,"UTF-8");//UTF-8->Unicode
3、字符流:
①父类:java.io.Reader/Writer(抽象类)
②子类:java.io.InputStreamReader/OutputStreamWriter
Ⅰ、编码转换流(读取数据需要刷新或关闭流)
InputStreamReader:
读取其他编码的字符,转成Unicode字符。read
OutputStreamWriter:
将内存中Unicode字符,转成其他编码的字符。write
Ⅱ、创建对象
InputStreamReader ir=new InputStreamReader(相接的字节流);//默认字符集
OutputStreamReader ir=new OutputStreamReader(相接的字节流,字符集);//指定字符集
③方法:(和抽象类的方法相同)
Ⅰ、Writer:
write(int c):int末尾两个字节,是char字符的两个字节值,只输出末尾两个字节。
write(char[] buf):输出数组中全部的字节值。
write(char[] buf,int from,int to):输出数组中的从from开始的num个字节值。
write(String s):输出字符串
Ⅱ、Reader:
read():单字节读取
read(char[] buf):多字节读取
④java.io.FileReader/FileWriter
内部是“编码转换流”接“文件字节流”,提供一种“编码转换流”代码的简化方式而已。
缺点:不能指定编码。
实质:InputStreamReader/OutputStreamWriter和FileInputStream/FileOutputStream的结合体。
4、字符缓冲/高级流
Ⅰ、java.io.BufferedReader/BufferedWriter
①提供字符缓冲区:
②方法:
BufferedReader的readLine()方法:读取一行字符串,不包含末尾换行,读取结束后超出返回NULL值。
Ⅱ、java.io.PrintWriter
①与PrintStream作用、用法完全相同,不同点:PrintStream只能接字节流,PrintWriter既能接字节流又能接字符流。
②方法
print():输出字符串不进行换行。
println():输出字符串并换行。
Ⅲ、练习
文本文件的复制,并转换编码。
5、java.io.ObjectInputStream/ObjectOutputStream
Ⅰ、对象序列化、反序列化,保存对象的值、变量等数据
①不序列化输出的成员:
static:静态
transient:临时、瞬间、瞬态(只在程序运行期间保存,不会持久保存,不会被恢复)
②序列化头部数据:
新建ObjectOutputStream对象时,会先输出4个头部字节值。
新建ObjectInputStream对象时,会先读取4个头部字节值,来确认后面的数据是对象队列化数据。
③序列化版本
旧版本数据,不能恢复成新版本的类型。
Ⅱ、创建对象
ObjectOutputStream out=new ObjectOutputStream(相接的流);
Ⅲ、方法
ObjectOutputStream
writeObject(Object obj):序列化输出一个对象
ObjectInputStream
readObject():读取并恢复一个对象,反序列化。
6、java.io.ByteArrayInputStream/ByteArrayOutputStream
①与内存中一个数组相接,读写数组中的字节数据,效率非常高,属于低级流,直接跟数据相接,需要和对象序列化类一起使用。
②创建对象
ByteArrayInputStream bais=new ByteArrayInputStream(byte[]数组);
ByteArrayOutputStream bais=new ByteArrayOutputStream();
输出流内部自动维护一个数组,输出的数据,都放在这个数组当中;
输出结束后,可以通过调用toByteArray()来取出内部的字节数组。
③方法
ByteArrayOutputStream中的toByteArray()方法:取出内部维护的数组。
注:使用这个字节流进行对象序列化相比ObjectOutputStream/ObjectInputStream效率会非常高,因为会直接在内存中读写数据。
二、XML
1、概念:
①可扩展的标记语言,XML是结构化的数据,由程序解析数据。
②作用:存储数据和传输数据。
android学习札记第7章之IO流三及XML初步
2、语法:
①头标记:必须在文档的第一个字节
②根元素:最外层根元素只能有一个
③元素必须有结束标签
④元素必须正确嵌套
⑤属性必须有属性值
⑥属性的值必须有引号,双引号、单引号都可以。
⑦转义实体:
<:<</P>
>:>
":"
':'
&:&
⑧机器在提取内部内容时,所有字符作为普通字符提取出来,不会做任何运算处理。
原样输出内容
注意事项
运用输入输出流时要注意字符编码必须一致,否则会出现乱码。
对象序列化使用ByteArrayInputStream/ByteArrayOutputStream在内存中处理读写,效率会非常高。
输入流和输出流要熟练掌握,才能在后续项目中运用自如。