lst文件、archive文件后缀修改为plist文件进行解析。
Mac上解析plist:
https://www.jianshu.com/p/e2b1ec14dade
查看plist:
https://www.jianshu.com/p/5f6e7d995a58
Java解析plist文件(转载):
plist文件有xml、binary(二进制)、ASCII三种存储格式。binary格式用xml方式解析会报:前言不允许有内容。
plist文件用Notepad++打开,编码-转为UTF-8编码。
如果plist文件用Notepad++打开发现是xml格式:
import org.xml.sax.Attributes;
import org.xml.sax.SAXException;
import org.xml.sax.helpers.DefaultHandler;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.parsers.SAXParser;
import javax.xml.parsers.SAXParserFactory;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Stack;
/**
* @Author: ZhangHao
* @Description: plist配置文件解析器
* @Date: 2020/6/21 16:59
* @Version: 1.0
*/
public class PlistHandler extends DefaultHandler {
private boolean isRootElement = false;
private boolean keyElementBegin = false;
private String key;
Stack<Object> stack = new Stack<Object>();
private boolean valueElementBegin = false;
private Object root;
@SuppressWarnings("unchecked")
public HashMap<String, Object> getMapResult() {
return (HashMap<String, Object>) root;
}
@SuppressWarnings("unchecked")
public List<Object> getArrayResult() {
return (List<Object>) root;
}
@Override
public void startDocument() throws SAXException {
System.out.println("开始解析");
}
@Override
public void endDocument() throws SAXException {
System.out.println("结束解析");
}
@SuppressWarnings("unchecked")
@Override
public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException {
if ("plist".equals(qName)) {
isRootElement = true;
}
if ("dict".equals(qName)) {
if (isRootElement) {
stack.push(new HashMap<String, Object>());// 压栈
isRootElement = !isRootElement;
} else {
Object object = stack.peek();
HashMap<String, Object> dict = new HashMap<String, Object>();
if (object instanceof ArrayList)
((ArrayList<Object>) object).add(dict);
else if (object instanceof HashMap)
((HashMap<String, Object>) object).put(key, dict);
stack.push(dict);
}
}
if ("key".equals(qName)) {
keyElementBegin = true;
}
if ("true".equals(qName)) {
HashMap<String, Object> parent = (HashMap<String, Object>) stack.peek();
parent.put(key, true);
}
if ("false".equals(qName)) {
HashMap<String, Object> parent = (HashMap<String, Object>) stack.peek();
parent.put(key, false);
}
if ("array".equals(qName)) {
if (isRootElement) {
ArrayList<Object> obj = new ArrayList<Object>();
stack.push(obj);
isRootElement = !isRootElement;
} else {
HashMap<String, Object> parent = (HashMap<String, Object>) stack.peek();
ArrayList<Object> obj = new ArrayList<Object>();
stack.push(obj);
parent.put(key, obj);
}
}
if ("string".equals(qName)) {
valueElementBegin = true;
}
}
/*
* 字符串解析(non-Javadoc)
*
* @see org.xml.sax.helpers.DefaultHandler#characters(char[], int, int)
*/
@SuppressWarnings("unchecked")
@Override
public void characters(char[] ch, int start, int length) throws SAXException {
System.out.println("characters:");
if (length > 0) {
if (keyElementBegin) {
key = new String(ch, start, length);
System.out.println("key:" + key);
}
if (valueElementBegin) {
if (HashMap.class.equals(stack.peek().getClass())) {
HashMap<String, Object> parent = (HashMap<String, Object>) stack.peek();
String value = new String(ch, start, length);
parent.put(key, value);
} else if (ArrayList.class.equals(stack.peek().getClass())) {
ArrayList<Object> parent = (ArrayList<Object>) stack.peek();
String value = new String(ch, start, length);
parent.add(value);
}
System.out.println("value:" + new String(ch, start, length));
}
}
}
@Override
public void endElement(String uri, String localName, String qName) throws SAXException {
if ("plist".equals(qName)) {
}
if ("key".equals(qName)) {
keyElementBegin = false;
}
if ("string".equals(qName)) {
valueElementBegin = false;
}
if ("array".equals(qName)) {
root = stack.pop();
}
if ("dict".equals(qName)) {
root = stack.pop();
}
}
public static void main(String[] args) throws ParserConfigurationException, SAXException, IOException {
SAXParserFactory factorys = SAXParserFactory.newInstance();
SAXParser saxparser = factorys.newSAXParser();
PlistHandler plistHandler = new PlistHandler();
saxparser.parse(new File(System.getProperty("user.dir") + "/test/test.plist").getAbsoluteFile().toURI().toString(), plistHandler);
HashMap<String, Object> hash = plistHandler.getMapResult();
ArrayList<Object> array = (ArrayList<Object>)plistHandler.getArrayResult();
}
}
如果是二进制格式:
二进制格式解析:
http://blog.afantree.com/ios/binary-plist-format-introduce.html
http://blog.afantree.com/ios/binary-plist-format-introduce-parsing.html
<dependency>
<groupId>com.googlecode.plist</groupId>
<artifactId>dd-plist</artifactId>
<version>1.23</version>
</dependency>
import com.dd.plist.BinaryPropertyListParser;
import com.dd.plist.NSObject;
import com.dd.plist.PropertyListFormatException;
import com.dd.plist.XMLPropertyListParser;
import org.xml.sax.SAXException;
import javax.xml.parsers.ParserConfigurationException;
import java.io.*;
import java.text.ParseException;
import java.util.HashMap;
import java.util.zip.GZIPInputStream;
/**
* @Author: ZhangHao
* @Description: plist配置文件解析器
* @Date: 2020/6/21 16:59
* @Version: 1.0
*/
public class PlistTest1 {
public static void main(String[] args) {
String filePath = System.getProperty("user.dir") + "/test/mmsetting.plist";
byte[] bytes = null;
try {
bytes = new FileInputStream(filePath).readAllBytes();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
if(bytes == null){
return;
}
// 传入byte[]
NSObject xx = null;
try {
xx = BinaryPropertyListParser.parse(bytes);
} catch (PropertyListFormatException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
// 你要看你的是什么类型,直接强转
HashMap obj = (HashMap) xx.toJavaObject();
// 获取节点
byte[] responseBody = (byte[]) obj.get("ResponseBody");
// GZIP解压
ByteArrayOutputStream out = new ByteArrayOutputStream();
ByteArrayInputStream in = new ByteArrayInputStream(responseBody);
try {
GZIPInputStream ungzip = new GZIPInputStream(in);
byte[] buffer = new byte[256];
int n;
while ((n = ungzip.read(buffer)) >= 0) {
out.write(buffer, 0, n);
}
} catch (IOException e) {
e.printStackTrace();
}
// 再次解析plist
NSObject body = null;
try {
body = XMLPropertyListParser.parse(out.toByteArray());
} catch (ParserConfigurationException e) {
e.printStackTrace();
} catch (ParseException e) {
e.printStackTrace();
} catch (SAXException e) {
e.printStackTrace();
} catch (PropertyListFormatException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
HashMap bodyMap = (HashMap) body.toJavaObject();
}
}
不知存储方式,选择终极方案:
import java.io.*;
import com.dd.plist.PropertyListParser;
public class PlistTest2 {
public static void main(String[] args) throws Exception {
File file = new File(System.getProperty("user.dir") + "/test/test.plist");
// 转换存放的路径
File file1 = new File(System.getProperty("user.dir") + "/test/test.xml");
PropertyListParser.convertToXml(file, file1);
}
}
报:"The binary property list contains a corrupted object offset table."则plist文件不是纯正的plist文件,需进一步分析。