本篇介绍json数据的读写和xml数据的序列化。
JSON和XML是目前常用的数据交换格式,相比而言,JSON更轻量,是目前BS架构里主流的数据交换格式;XML则常用作配置文件。
下面通过示例演示两种格式的常用读写方法,先做好前戏,比如新建一个Student类:
public class Student {
public Student() {
}
public Student(String name, Integer age, Date birthday) {
Name = name;
Age = age;
Birthday = birthday;
}
public String Name;
public Integer Age;
public Date Birthday;
@NonNull
@Override
public String toString() {
return String.format("Name:%s Age:%d Birthday:%s",Name,Age,Birthday);
}
}
JSON读写
JSON读写主要用到两个类JSONObject和JSONArray:
- JSONObject:JSON对象,用{}来界定一个JSON对象;
- JSONArray:JSON数组,用[]来界定一个JSON数组;
- 上述两个类型可互相嵌套
构建JSON对象
假设1个班级有4个学生,现在要构建这个班级对象。
private void Export2JSON() {
try {
JSONObject root = new JSONObject();
root.put("class", "三年二班");
JSONArray jsonArray = new JSONArray();
for (int i = 0; i < studentList.size(); i++) {
JSONObject stu = new JSONObject();
stu.put("name", studentList.get(i).Name);
stu.put("age", studentList.get(i).Age);
stu.put("birthday", studentList.get(i).Birthday.toLocaleString());
jsonArray.put(stu);
}
root.put("students", jsonArray);
System.out.println(root.toString());
} catch (JSONException e) {
e.printStackTrace();
}
}
代码没什么难理解的,最后构建好的json对象如下:
{
"class":"三年二班",
"students":[
{"birthday":"1987/10/12","age":25,"name":"八神"},
{"birthday":"1998/11/4","age":25,"name":"草薙"},
{"birthday":"1990/3/18","age":22,"name":"K'"},
{"birthday":"1992/7/8,","age":20,"name":"ASH"}]
}
读取JSON数据
我们在asset文件夹中创建一个students.json文件,并将刚才的json对象拷贝进去。
private void ReadJSON() {
try {
//读取文件到字符串中
InputStreamReader isr = new InputStreamReader(getAssets().open("students.json"), "UTF-8");
BufferedReader bufferedReader = new BufferedReader(isr);
String line;
StringBuilder builder = new StringBuilder();
while ((line = bufferedReader.readLine()) != null) {
builder.append(line);
}
//从字符串中解析JSON对象
JSONObject jsonObject = new JSONObject(builder.toString());
System.out.println("class:" + jsonObject.getString("class"));
JSONArray jsonArray = jsonObject.getJSONArray("students");
for (int i = 0; i < jsonArray.length(); i++) {
System.out.println("学生" + i);
System.out.println(jsonArray.getJSONObject(i).getString("name"));
System.out.println(jsonArray.getJSONObject(i).getInt("age"));
System.out.println(jsonArray.getJSONObject(i).getString("birthday"));
}
} catch (Exception e) {
e.printStackTrace();
}
}
可以直接从字符串解析到JSON。注意的是,要判断字符串代表的是JSONObject还是JSONArray,再使用对应的类型去解析。
XML读写
对XML的读写有两种方式,利用DocumentBuilder和序列化,这里介绍序列化的方式。
构建xml文件
将4个学生的信息构建成xml文件,存储到程序路径下:
private void Export2XML() {
try {
XmlSerializer serializer = Xml.newSerializer();
FileOutputStream fos = openFileOutput("students.xml", MODE_PRIVATE); //获取输入流
serializer.setOutput(fos, "utf-8");//设置输入流和编码
// 开始文档
serializer.startDocument("utf-8", true);
serializer.startTag(null, "students");
// 循环写入对象
for (int i = 0; i < studentList.size(); i++) {
serializer.startTag(null, "student");
serializer.attribute("", "name", studentList.get(i).Name);
serializer.attribute("", "age", studentList.get(i).Age.toString());
serializer.startTag(null, "birthday");
serializer.text(studentList.get(i).Birthday.toLocaleString());
serializer.endTag(null, "birthday");
serializer.endTag(null, "student");
}
serializer.endTag(null, "students");
serializer.endDocument();// 结束文档
System.out.println("序列化完成");
} catch (IOException e) {
e.printStackTrace();
}
}
主要用到XmlSerializer 类,方法如下:
- startDocument/endDocument 开始/结束一个xml文档
- startTag/endTag 开始/结束一个xml节点
- attribute 在当前标签加入属性
-
text 给当前标签设置值
上面代码构建出的xml文件形式如下:
<?xml version="1.0" encoding="utf-8"?>
<students>
<student name="八神" age="25">
<birthday>Nov 12, 3887 12:00:00 AM</birthday>
</student>
...
</students>
序列化xml文件
使用XmlPullParser,工作原理是通过getEventType方法逐
标签
的遍历xml文件,并取出其中的text和attrbute。
我们将刚才构建的xml文件序列化到实体类中:
private void ReadXML() {
try {
XmlPullParser parser = Xml.newPullParser();
FileInputStream fis = openFileInput("students.xml");
parser.setInput(fis, "utf-8");
int eventType = parser.getEventType();
List<Student> list = null;
Student stu = null;
while (eventType != XmlPullParser.END_DOCUMENT) {
switch (eventType) {
case XmlPullParser.START_TAG:
if (parser.getName().equals("students")) { //读到根标签,创建数组
list = new ArrayList<Student>();
} else if (parser.getName().equals("student")) { //读到student说明要开始创建对象
stu = new Student();
//设置对象的属性
stu.Name = parser.getAttributeValue("", "name");
stu.Age = Integer.parseInt(parser.getAttributeValue("", "age"));
} else if (parser.getName().equals("birthday")) {
stu.Birthday = new Date(Date.parse(parser.nextText()));//nextText调用后parser会指到EndTag
}
break;
case XmlPullParser.END_TAG:
//读到student,说明一个对象对去完毕添加到list集合中,重置stu
if (parser.getName().equals("student")) {
list.add(stu);
stu = null;
}
break;
}
//一轮结束后要将解析器推进
eventType = parser.next();
}
System.out.println(list);
} catch (Exception e) {
e.printStackTrace();
}
}
主要用到XmlPullParser 的如下几个方法:
- getEventType 获取当前标签类型,一般有START_TAG, END_TAG, TEXT、START_DOCUMENT、END_DOCUMENT几种类型;
- next 推至下个标签
- getName 获取当前标签名字
- getAttributeValue 获取当前标签内的属性值
- getText 获取当前标签的text
- nextText 获取当前标签的text,并推至EndTag标签。
版权声明:本文为SHENCHEN1987原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。