1. 背景
在日常开发过程中,经常遇到程序读取文件,将文件数据转换为对象,程序通过对象传输数据,或者通过对象读取数据。同时也会经常遇到对象数据写入文件操作。
如果采用常规的文件读写,然后再进行赋值;那么将耗费很多时间码代码实现,同时,如果在文件参数较多的情况下,采用常规操作将是一个重大工程量。囧o(╯□╰)o
那么软件前辈经过日夜奋进,不断创新,总结开发出很多优秀的反序列化及序列化工具/sdk/库,如下图所示
通过序列化&反序列化sdk,大大提高软件操作文件效率。
2. 方案
2.1 json
推荐方案:阿里的 fastjson
2.1.1 fastjson
Fastjson 是一个 Java 库,可以将 Java 对象转换为 JSON 格式,当然它也可以将 JSON 字符串转换为 Java 对象。Fastjson 可以操作任何 Java 对象,即使是一些预先存在的没有源码的对象。
Android使用要点:
- gradle导入
implementation 'com.alibaba:fastjson:1.1.71.android'
- 反序列化:
> > 示例json:
{
"id":"12345678",
"version":"202311111",
"code":"100001",
"data":[
{
"name": "MSG_P1",
"value":"610000",
"count":1,
"accuracy":1
},
{
"name": "MSG_P2",
"value":"5 15 25 35 45 55 65 75 85 95 105 115 125 135 145 155 165 175 185 195 205 215 225 235",
"count":24,
"accuracy":10
}
]
}
> > 创建对象
package com.auto.utils
import com.alibaba.fastjson.annotation.JSONType;
import java.util.ArrayList;
import java.util.List;
@JSONType(orders={"id","version","code","data"}) //序列化、反序列化顺序
public class JsonMsg {
private String id;
private String version;
private String code;
private List<JsonData> data= new ArrayList<>();
public void setId(String id) {
this.id= id;
}
public void setVersion(String version) {
this.version= version;
}
public void setCode(String code) {
this.code= code;
}
public void setJsonData(List<JsonData> data) {
this.data= data;
}
public String getId() {
return id;
}
public String getVersion() {
return version;
}
public String getCode() {
return code;
}
public List<JsonData> getJsonData() {
return data;
}
}
package com.auto.utils;
import com.alibaba.fastjson.annotation.JSONType;
@JSONType(orders={"name","value","count","accuracy"})//序列化、反序列化顺序
public class JsonData {
private String name;
private String value;
private int count;
private int accuracy;
public void setName(String name) {
this.name = name;
}
public void setValue(String value) {
this.value = value;
}
public void setCount(int count) {
this.count = count;
}
public void setAccuracy(int accuracy) {
this.accuracy = accuracy;
}
public String getName() {
return name;
}
public String getValue() {
return value;
}
public int getCount() {
return count;
}
public int getAccuracy() {
return accuracy;
}
}
> > 接口: JSON.parseObject
方法原型:
public static final <T> T parseObject(String text, Class<T> clazz) {
return parseObject(text, clazz, new Feature[0]);
}
> > 使用://伪代码
private JsonMsg jsonMsg;
...
try {
String json_str = loadJSONFromAsset(mContext,"test");
JSONObject jsonObject = JSON.parseObject(json_str, Feature.OrderedField);//
if(jsonObject instanceof JSONObject) {
jsonMsg = JSON.parseObject(jsonObject.toJSONString(),JsonMsg .class);
}else{
Log.e(TAG,"jsonObject is not JSONObject.");
}
}catch (Exception e){
e.printStackTrace();
}
/**
* load json file from assset.
* @param context
* @param fileName
* @return
*/
public static synchronized String loadJSONFromAsset(Context context,String fileName) {
String json = null;
try {
InputStream is = context.getAssets().open(fileName + ".json");
int size = is.available();
byte[] buffer = new byte[size];
is.read(buffer);
is.close();
json = new String(buffer, "UTF-8");
} catch (IOException ex) {
ex.printStackTrace();
return null;
}
return json;
}
- 序列化
>> 接口 : JSON.toJSONString
方法原型:
public static final String toJSONString(Object object) {
return toJSONString(object, SerializeConfig.globalInstance, null, null, DEFAULT_GENERATE_FEATURE);
}
/**
* @since 1.2.11
*/
public static final String toJSONString(Object object, SerializerFeature... features) {
return toJSONString(object, DEFAULT_GENERATE_FEATURE, features);
}
public static final String toJSONString(Object object, int defaultFeatures, SerializerFeature... features) {
return toJSONString(object, SerializeConfig.globalInstance, null, null, defaultFeatures, features);
}
/**
* @since 1.1.14
*/
public static final String toJSONStringWithDateFormat(Object object, String dateFormat,
SerializerFeature... features) {
return toJSONString(object, SerializeConfig.globalInstance, null, dateFormat, DEFAULT_GENERATE_FEATURE, features);
}
public static final String toJSONString(Object object, SerializeFilter filter, SerializerFeature... features) {
return toJSONString(object, SerializeConfig.globalInstance, new SerializeFilter[] {filter}, null, DEFAULT_GENERATE_FEATURE, features);
}
public static final String toJSONString(Object object, SerializeFilter[] filters, SerializerFeature... features) {
return toJSONString(object, SerializeConfig.globalInstance, filters, null, DEFAULT_GENERATE_FEATURE, features);
}
public static final String toJSONString(Object object, SerializeConfig config, SerializerFeature... features) {
return toJSONString(object, config, null, null, DEFAULT_GENERATE_FEATURE, features);
}
public static final String toJSONString(Object object, SerializeConfig config, SerializeFilter filter,
SerializerFeature... features) {
return toJSONString(object, config, new SerializeFilter[] {filter}, null, DEFAULT_GENERATE_FEATURE, features);
}
public static final String toJSONString(Object object, SerializeConfig config, SerializeFilter[] filters,
SerializerFeature... features) {
return toJSONString(object, config, filters, null, DEFAULT_GENERATE_FEATURE, features);
}
public static final String toJSONStringZ(Object object, SerializeConfig mapping, SerializerFeature... features) {
return toJSONString(object, SerializeConfig.globalInstance, null, null, 0, features);
}
> > 使用:
/**
* //先执行static代码块,再执行该方法
* //是否输出值为null的字段,默认为false
* JSON.DEFAULT_GENERATE_FEATURE |= SerializerFeature.WriteMapNullValue.getMask();
* //数值字段如果为null,输出为0,而非null
* JSON.DEFAULT_GENERATE_FEATURE |= SerializerFeature.WriteNullNumberAsZero.getMask();
* //List字段如果为null,输出为[],而非null
* JSON.DEFAULT_GENERATE_FEATURE |= SerializerFeature.WriteNullListAsEmpty.getMask();
* //字符类型字段如果为null,输出为 "",而非null
* JSON.DEFAULT_GENERATE_FEATURE |= SerializerFeature.WriteNullStringAsEmpty.getMask()
*/
JSON.DEFAULT_GENERATE_FEATURE |= SerializerFeature.WriteMapNullValue.mask;
Log.e(TAG,"class -> json:" + JSON.toJSONString(jsonMsg));//jsonMsg 在反序列化中有定义
saveJSONtoStorage(FilesUtils.getJsonFile(),JSON.toJSONString(jsonMsg));
/**
* saveJSONtoStorage
* @param filePath
* @param jsonString
* @return
*/
public static synchronized void saveJSONtoStorage(String filePath,String jsonString) {
String json = null;
//TODO
try {
File file = new File(filePath);
if (!file.exists()) {
file.createNewFile();
} else {
return;
}
}catch (Exception e){
e.printStackTrace();
return;
}
try {
if(filePath == null){
Log.e(TAG,"saveJSONtoStorage filePath is null");
return;
}
File file = new File(filePath);
FileWriter fw = null;
if (file.exists()) {
fw = new FileWriter(file, true);
} else {
fw = new FileWriter(file, false);
}
fw.write(String.format("%s", jsonString));
fw.write(13);
fw.write(10);
fw.flush();
fw.close();
} catch (Throwable ex) {
ex.printStackTrace();
}
}
2.1.2 jackson
//TODO
2.2 xml
推荐方案:jackson-dataformat-xml
Android使用步骤:
- gradle导入:
implementation 'com.fasterxml.jackson.dataformat:jackson-dataformat-xml:2.14.2'
implementation 'javax.xml.stream:stax-api:1.0-2'
- xml文件示例:
<?xml version="1.0" encoding="utf-8"?>
<XmlMsg>
<id>12345678</vehicleID>
<vcuVersion>202311111</vcuVersion>
<checkCode>100001</checkCode>
<xmlDataList>
<xmlData>
<name>MSG_P1</name>
<value>610000</value>
<count>1</count>
<accuracy>1</accuracy>
</xmlData>
<xmlData>
<name>MSG_P2</name>
<value>5 15 25 35 45 55 65 75 85 95 105 115 125 135 145 155 165 175 185 195 205 215 225 235</value>
<count>24</count>
<accuracy>10</accuracy>
</xmlData>
</xmlDataList>
</XmlMsg>
- 创建对象
package com.auto.utils
import com.fasterxml.jackson.annotation.JsonPropertyOrder;
import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlElementWrapper;
import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlProperty;
import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlRootElement;
import java.util.ArrayList;
import java.util.List;
@JacksonXmlRootElement(localName = "XmlMsg")
@JsonPropertyOrder({"id","version","code","data"}) //序列化、反序列化顺序
public class XmlMsg {
@JacksonXmlProperty(localName = "id")
private String id;
@JacksonXmlProperty(localName = "version")
private String version;
@JacksonXmlProperty(localName = "code")
private String code;
@JacksonXmlElementWrapper(localName = "xmlDataList")
@JacksonXmlProperty(localName = "xmlData")
private List<xmlData> data= new ArrayList<>();
public void setId(String id) {
this.id= id;
}
public void setVersion(String version) {
this.version= version;
}
public void setCode(String code) {
this.code= code;
}
public void setJsonData(List<JsonData> data) {
this.data= data;
}
public String getId() {
return id;
}
public String getVersion() {
return version;
}
public String getCode() {
return code;
}
public List<JsonData> getJsonData() {
return data;
}
}
package com.auto.utils;
import com.fasterxml.jackson.annotation.JsonPropertyOrder;
import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlProperty;
@JsonPropertyOrder({"name", "value", "count","accuracy"})//序列化、反序列化顺序
public class JsonData {
@JacksonXmlProperty(localName = "name")
private String name;
@JacksonXmlProperty(localName = "value")
private String value;
@JacksonXmlProperty(localName = "count")
private int count;
@JacksonXmlProperty(localName = "accuracy")
private int accuracy;
public void setName(String name) {
this.name = name;
}
public void setValue(String value) {
this.value = value;
}
public void setCount(int count) {
this.count = count;
}
public void setAccuracy(int accuracy) {
this.accuracy = accuracy;
}
public String getName() {
return name;
}
public String getValue() {
return value;
}
public int getCount() {
return count;
}
public int getAccuracy() {
return accuracy;
}
}
- 序列化&反序列化
try {
//XNL反序列化为对象
AssetManager am = context.getResources().getAssets();
InputStream in = am.open( "test" + ".xml");
ObjectMapper xmlMapper = XmlMapper.builder(new XmlFactory(new WstxInputFactory(), new WstxOutputFactory())).build();
XmlMsg xmlMsg = xmlMapper.readValue(in,XmlMsg .class);
//对象序列化为XML
xmlMapper.enable(SerializationFeature.INDENT_OUTPUT);
xmlMapper.writeValue(new File(FilesUtils.getXmlFile()), xmlMsg );
}catch (Exception e){
e.printStackTrace();
}