Android 包信息工具类


  /**
  AndroidInfoUtils:安卓游戏包信息工具类
**/
1
public class AndroidInfoUtils 2 { 3 @SuppressWarnings("unchecked") 4 public static ApkInfo getAndroidInfo(String apkPath) throws DocumentException 5 { 6 ApkInfo apkinfo = new ApkInfo(); 7 File file = new File(apkPath); 8 // 获得APK文件名称 9 apkinfo.setApkName(file.getName()); 10 // 获得APK文件大小 11 apkinfo.setApkSize(convertFileSize(file.length())); 12 // 获得APK文件原始大小 13 apkinfo.setApkByteSize(file.length()); 14 15 String xml = AXMLPrinter2.getManifestXMLFromAPK(apkPath); 16 //System.out.println(xml); 17 StringReader read = new StringReader(xml); 18 InputSource scource = new InputSource(read); 19 SAXReader sax = new SAXReader(); 20 Document root = sax.read(scource); 21 Element uses_sdk = (Element) root.selectSingleNode("//uses-sdk"); 22 // 获取APK支持的Android SDK版本 23 apkinfo.setApkMinsdkversion(uses_sdk.attributeValue("minSdkVersion")); 24 25 // zhouning 设置sdk目标版本 26 apkinfo.setApkTargetSdkVersion(uses_sdk.attributeValue("targetSdkVersion")); 27 28 Element manifest = (Element) root.selectSingleNode("//manifest"); 29 // 获取APK版本 30 apkinfo.setApkVersion(manifest.attributeValue("versionName")); 31 // 获取APK包名 32 apkinfo.setApkPageage(manifest.attributeValue("package")); 33 // 获取APK版本代码 34 apkinfo.setApkVersionCode(manifest.attributeValue("versionCode")); 35 List<Element> elements = root.selectNodes("//uses-permission"); 36 37 38 if (CommonUtil.isNotEmpty(elements)) { 39 StringBuffer apkUserPermissionBuff = new StringBuffer(); 40 for (Element el : elements) 41 { 42 apkUserPermissionBuff.append("|").append(el.attributeValue("name")); 43 } 44 45 String apkUserStr = apkUserPermissionBuff.toString(); 46 47 if (CommonUtil.isNotEmpty(apkUserStr)) { 48 apkinfo.setApkUserpermission(apkUserStr.substring(1)); 49 } 50 } 51 52 53 //增加是否存在SDK的设置 54 apkinfo.setExistSdk(AXMLPrinter2.isExistSdk(apkPath)); 55 // 设置SDK版本 56 apkinfo.setSdkVersion(AXMLPrinter2.getSdkVersion(apkPath)); 57 // 设置SDK类型 58 apkinfo.setApkSdkType(AXMLPrinter2.getSdkType(apkPath)); 59 60 return apkinfo; 61 } 62 63 public static String convertFileSize(long filesize) 64 { 65 String strUnit = "Bytes"; 66 String strAfterComma = ""; 67 int intDivisor = 1; 68 if (filesize >= 1024 * 1024) 69 { 70 strUnit = "MB"; 71 intDivisor = 1024 * 1024; 72 } else if (filesize >= 1024) 73 { 74 strUnit = "KB"; 75 intDivisor = 1024; 76 } 77 if (intDivisor == 1){ 78 return filesize + " " + strUnit; 79 } 80 81 strAfterComma = "" + 100 * (filesize % intDivisor) / intDivisor; 82 if (strAfterComma.equals("")) 83 strAfterComma = ".0"; 84 85 return filesize / intDivisor + "." + strAfterComma + " " + strUnit; 86 } 87 88 public static ThreeNetsContent getThreeNetsContent(String apkPath) 89 { 90 return AXMLPrinter2.getThreeNetsContent(apkPath); 91 } 92 }

 

  所用到的ApkInfo

 

  

  1 public class ApkInfo {
  2     
  3     // APK游戏名称
  4     private String apkName;
  5 
  6     // APK游戏大小
  7     private String apkSize;
  8 
  9     // APK游戏包名称
 10     private String apkPageage;
 11 
 12     // APK游戏版本
 13     private String apkVersion;
 14 
 15     // APK游戏版本代码
 16     private String apkVersionCode;
 17 
 18     // APK游戏适应Android SDK版本
 19     private String apkMinsdkversion;
 20 
 21     // APK游戏用户权限
 22     private String apkUserpermission;
 23 
 24     // APK游戏字节大小
 25     private long apkByteSize;
 26 
 27     // zhouning SDK目标版本
 28     private String apkTargetSdkVersion;
 29 
 30     private boolean isExistSdk;
 31     
 32     //add by mzz sdk类型
 33     private String apkSdkType;
 34     
 35     /**
 36      * SDK版本
 37      */
 38     private String sdkVersion;
 39     
 40     
 41 
 42     public boolean isExistSdk() {
 43         return isExistSdk;
 44     }
 45 
 46     public void setExistSdk(boolean isExistSdk) {
 47         this.isExistSdk = isExistSdk;
 48     }
 49 
 50     public String getApkName() {
 51         return apkName;
 52     }
 53 
 54     public void setApkName(String apkName) {
 55         this.apkName = apkName;
 56     }
 57 
 58     public String getApkSize() {
 59         return apkSize;
 60     }
 61 
 62     public void setApkSize(String apkSize) {
 63         this.apkSize = apkSize;
 64     }
 65 
 66     public String getApkPageage() {
 67         return apkPageage;
 68     }
 69 
 70     public void setApkPageage(String apkPageage) {
 71         this.apkPageage = apkPageage;
 72     }
 73 
 74     public String getApkVersion() {
 75         return apkVersion;
 76     }
 77 
 78     public void setApkVersion(String apkVersion) {
 79         this.apkVersion = apkVersion;
 80     }
 81 
 82     public String getApkVersionCode() {
 83         return apkVersionCode;
 84     }
 85 
 86     public void setApkVersionCode(String apkVersionCode) {
 87         this.apkVersionCode = apkVersionCode;
 88     }
 89 
 90     public String getApkMinsdkversion() {
 91         return apkMinsdkversion;
 92     }
 93 
 94     public void setApkMinsdkversion(String apkMinsdkversion) {
 95         this.apkMinsdkversion = apkMinsdkversion;
 96     }
 97 
 98     public String getApkUserpermission() {
 99         return apkUserpermission;
100     }
101 
102     public void setApkUserpermission(String apkUserpermission) {
103         this.apkUserpermission = apkUserpermission;
104     }
105 
106     public long getApkByteSize() {
107         return apkByteSize;
108     }
109 
110     public void setApkByteSize(long apkByteSize) {
111         this.apkByteSize = apkByteSize;
112     }
113 
114     public String getApkTargetSdkVersion() {
115         return apkTargetSdkVersion;
116     }
117 
118     public void setApkTargetSdkVersion(String apkTargetSdkVersion) {
119         this.apkTargetSdkVersion = apkTargetSdkVersion;
120     }
121 
122     public String getSdkVersion()
123     {
124         return sdkVersion;
125     }
126 
127     public void setSdkVersion(String sdkVersion)
128     {
129         this.sdkVersion = sdkVersion;
130     }
131 
132     public void setApkSdkType(String apkSdkType) {
133         this.apkSdkType = apkSdkType;
134     }
135 
136     public String getApkSdkType() {
137         return apkSdkType;
138     }
139     
140     
141 }

  

  解析Android 主文件  AndroidManifest.xml

  

  1 import java.io.BufferedReader;
  2 import java.io.ByteArrayInputStream;
  3 import java.io.File;
  4 import java.io.IOException;
  5 import java.io.InputStreamReader;
  6 import java.security.interfaces.RSAPublicKey;
  7 import java.security.spec.X509EncodedKeySpec;
  8 import java.util.zip.ZipEntry;
  9 import java.util.zip.ZipFile;
 10 
 11 import org.apache.commons.codec.binary.Base64;
 12 import org.jdom.Document;
 13 import org.jdom.Element;
 14 import org.jdom.input.SAXBuilder;
 15 
 16 import android.content.res.AXmlResourceParser;
 17 
 18 import com.huawei.bme.commons.util.debug.DebugLog;
 19 import com.huawei.bme.commons.util.debug.LogFactory;
 20 import com.huawei.igop.common.constants.PropertyKey;
 21 import com.huawei.igop.common.plist.NSObject;
 22 import com.huawei.igop.common.plist.PropertyListParser;
 23 import com.huawei.igop.partner.bean.ThreeNetsContent;
 24 import com.huawei.igop2.common.utils.RSAUtils;
 25 
 26 public class AXMLPrinter2 {
 27 
 28 
 29     @SuppressWarnings("unused")
 30     private static final String DEFAULT_XML = "AndroidManifest.xml";
 31     private static final float[] RADIX_MULTS = { 0.0039063F, 3.051758E-005F,
 32             1.192093E-007F, 4.656613E-010F };
 33     private static final String[] DIMENSION_UNITS = { "px", "dip", "sp", "pt",
 34             "in", "mm", "", "" };
 35     private static final String[] FRACTION_UNITS = { "%", "%p", "", "", "", "",
 36             "", "" };
 37 
 38     public static String getManifestXMLFromAPK(String apkPath) {
 39         ZipFile file = null;
 40         StringBuilder xmlSb = new StringBuilder(100);
 41         try {
 42             int type;
 43             File apkFile = new File(apkPath);
 44             file = new ZipFile(apkFile, 1);
 45             ZipEntry entry = file.getEntry("AndroidManifest.xml");
 46 
 47             AXmlResourceParser parser = new AXmlResourceParser();
 48             parser.open(file.getInputStream(entry));
 49 
 50             StringBuilder sb = new StringBuilder(10);
 51             @SuppressWarnings("unused")
 52             String indentStep = "\t";
 53 
 54             while ((type = parser.next()) != 1) {
 55                 switch (type) {
 56                 case 0:
 57                     log(xmlSb, "<?xml version=\"1.0\" encoding=\"utf-8\"?>",
 58                             new Object[0]);
 59                     break;
 60                 case 2:
 61                     log(false,
 62                             xmlSb,
 63                             "%s<%s%s",
 64                             new Object[] { sb,
 65                                     getNamespacePrefix(parser.getPrefix()),
 66                                     parser.getName() });
 67                     sb.append("\t");
 68 
 69                     int namespaceCountBefore = parser.getNamespaceCount(parser
 70                             .getDepth() - 1);
 71                     int namespaceCount = parser.getNamespaceCount(parser
 72                             .getDepth());
 73 
 74                     for (int i = namespaceCountBefore; i != namespaceCount; ++i) {
 75                         log(xmlSb,
 76                                 "%sxmlns:%s=\"%s\"",
 77                                 new Object[] {
 78                                         (i == namespaceCountBefore) ? "  " : sb,
 79                                         parser.getNamespacePrefix(i),
 80                                         parser.getNamespaceUri(i) });
 81                     }
 82 
 83                     int i = 0;
 84                     for (int size = parser.getAttributeCount(); i != size; ++i) {
 85                         log(false,
 86                                 xmlSb,
 87                                 "%s%s%s=\"%s\"",
 88                                 new Object[] {
 89                                         " ",
 90                                         getNamespacePrefix(parser
 91                                                 .getAttributePrefix(i)),
 92                                         parser.getAttributeName(i),
 93                                         getAttributeValue(parser, i) });
 94                     }
 95 
 96                     log(xmlSb, ">", new Object[0]);
 97                     break;
 98                 case 3:
 99                     sb.setLength(sb.length() - "\t".length());
100                     log(xmlSb,
101                             "%s</%s%s>",
102                             new Object[] { sb,
103                                     getNamespacePrefix(parser.getPrefix()),
104                                     parser.getName() });
105                     break;
106                 case 4:
107                     log(xmlSb, "%s%s", new Object[] { sb, parser.getText() });
108                 case 1:
109                 }
110 
111             }
112 
113             parser.close();
114         } catch (Exception e) {
115             e.printStackTrace();
116         } finally {
117             if (file != null) {
118                 try {
119                     file.close();
120                 } catch (IOException e) {
121                     
122                 }
123             }
124         }
125         return xmlSb.toString();
126     }
127 
128     public static boolean isExistSdk(String apkPath) {
129         ZipFile file = null;
130         try {
131             File apkFile = new File(apkPath);
132             file = new ZipFile(apkFile, 1);
133             ZipEntry entryCharge = file.getEntry("assets/Charge.xml");
134             ZipEntry entryConsumeCode = file
135                     .getEntry("assets/ConsumeCodeInfo.xml");
136             if (entryCharge != null && entryConsumeCode != null) {
137                 return true;
138             }
139         } catch (Exception e) {
140             e.printStackTrace();
141         } finally {
142             if (file != null) {
143                 try {
144                     file.close();
145                 } catch (IOException e) {
146                     e.printStackTrace();
147                 }
148             }
149         }
150         return false;
151     }
152     
153     private static String getNamespacePrefix(String prefix) {
154         if ((prefix == null) || (prefix.length() == 0)) {
155             return "";
156         }
157         return prefix + ":";
158     }
159 
160     private static String getAttributeValue(AXmlResourceParser parser, int index) {
161         int type = parser.getAttributeValueType(index);
162         int data = parser.getAttributeValueData(index);
163         if (type == 3) {
164             return parser.getAttributeValue(index);
165         }
166         if (type == 2) {
167             return String.format("?%s%08X", new Object[] { getPackage(data),
168                     Integer.valueOf(data) });
169         }
170         if (type == 1) {
171             return String.format("@%s%08X", new Object[] { getPackage(data),
172                     Integer.valueOf(data) });
173         }
174         if (type == 4) {
175             return String.valueOf(Float.intBitsToFloat(data));
176         }
177         if (type == 17) {
178             return String.format("0x%08X",
179                     new Object[] { Integer.valueOf(data) });
180         }
181         if (type == 18) {
182             return ((data != 0) ? "true" : "false");
183         }
184         if (type == 5) {
185             return Float.toString(complexToFloat(data))
186                     + DIMENSION_UNITS[(data & 0xF)];
187         }
188         if (type == 6) {
189             return Float.toString(complexToFloat(data))
190                     + FRACTION_UNITS[(data & 0xF)];
191         }
192         if ((type >= 28) && (type <= 31)) {
193             return String.format("#%08X",
194                     new Object[] { Integer.valueOf(data) });
195         }
196         if ((type >= 16) && (type <= 31)) {
197             return String.valueOf(data);
198         }
199         return String.format("<0x%X, type 0x%02X>",
200                 new Object[] { Integer.valueOf(data), Integer.valueOf(type) });
201     }
202 
203     private static String getPackage(int id) {
204         if (id >>> 24 == 1) {
205             return "android:";
206         }
207         return "";
208     }
209 
210     private static void log(StringBuilder xmlSb, String format,
211             Object[] arguments) {
212         log(true, xmlSb, format, arguments);
213     }
214 
215     private static void log(boolean newLine, StringBuilder xmlSb,
216             String format, Object[] arguments) {
217         xmlSb.append(String.format(format, arguments));
218         if (newLine)
219             xmlSb.append("\n");
220     }
221 
222     public static float complexToFloat(int complex) {
223         return ((complex & 0xFFFFFF00) * RADIX_MULTS[(complex >> 4 & 0x3)]);
224     }
225     
226     public static String getSdkVersion(String apkPath)
227     {
228         String sdkVersion = null;
229         ZipFile zipfile = null;
230         try
231         {
232             File apkFile = new File(apkPath);
233             zipfile = new ZipFile(apkFile, 1);
234             ZipEntry config = zipfile.getEntry("assets/Config.xml");
235             if (null != config)
236             {
237                 Document doc = new SAXBuilder().build(zipfile.getInputStream(config));
238                 sdkVersion = doc.getRootElement().getChildTextTrim("SDKVersion");
239             }
240         }
241         catch (Exception e)
242         {
243             DEBUGGER.error("Failed to getSdkVersion", e);
244         }
245         finally
246         {
247             closeZipFile(zipfile);
248         }
249         return sdkVersion;
250     }
251     
252     public static String getSdkType(String apkPath)
253     {
254         String SdkType = null;
255         ZipFile zipfile = null;
256         try
257         {
258             File apkFile = new File(apkPath);
259             zipfile = new ZipFile(apkFile, 1);
260             ZipEntry config = zipfile.getEntry("assets/ConfigExt.xml");
261             if (null != config)
262             {
263                 //配置文件内容,由SDK通过RSA 私钥加密,iGop从包体读出时,通过RSA公钥解密(防止CP篡改)。
264                 BufferedReader in = new BufferedReader(new InputStreamReader(zipfile.getInputStream(config)));
265                 StringBuffer strBuffer = new StringBuffer();
266                 String buffer = null;
267                 while (null != (buffer = in.readLine()))
268                 {
269                     //得到密文
270                     strBuffer.append(buffer);
271                 }
272                 String key = PropertyUtil.getString(PropertyKey.SDK_TYPE_PUBLICKEY);
273                 X509EncodedKeySpec pubX509new = new X509EncodedKeySpec(Base64.decodeBase64(key.getBytes()));
274                 RSAPublicKey pukey1 = RSAUtils.getPublicKey(pubX509new);
275                 String jiewen = RSAUtils.decryptByPublicKey(strBuffer.toString(), pukey1);
276                 Document doc = new SAXBuilder().build(new ByteArrayInputStream(jiewen.getBytes()));
277                 SdkType = doc.getRootElement().getChildTextTrim("SDKType");
278                 
279             }
280         }
281         catch (Exception e)
282         {
283             DEBUGGER.error("Failed to getSdkType", e);
284         }
285         finally
286         {
287             closeZipFile(zipfile);
288         }
289         return SdkType;
290     }
291 
292     public static void closeZipFile(ZipFile zipfile)
293     {
294         if (null != zipfile)
295         {
296             try
297             {
298                 zipfile.close();
299             }
300             catch (IOException e)
301             {
302                 DEBUGGER.error("Failed to close ZipFile", e);
303             }
304         }
305     }
306     
307     public static ThreeNetsContent getThreeNetsContent(String apkPath)
308     {
309         ZipFile zipfile = null;
310         ThreeNetsContent threeNetsContent = null;
311         try
312         {
313             File file = new File(apkPath);
314             zipfile = new ZipFile(file, 1);
315             ZipEntry zipEntry = zipfile.getEntry("assets/touchpayservice.xml");
316             if (null == zipEntry)
317             {
318                 return null;
319             }
320             
321             threeNetsContent = new ThreeNetsContent();
322             Document doc = new SAXBuilder().build(zipfile.getInputStream(zipEntry));
323             Element element = doc.getRootElement();
324             threeNetsContent.setCmServiceId(element.getChildTextTrim("cm_serviceid"));
325             threeNetsContent.setCuServiceId(element.getChildTextTrim("cu_serviceid"));
326             threeNetsContent.setCtServiceId(element.getChildTextTrim("ct_serviceid"));
327         }
328         catch (Exception e)
329         {
330             DEBUGGER.error("Failed to getThreeNetsContent", e);
331         }
332         finally
333         {
334             closeZipFile(zipfile);
335         }
336         
337         return threeNetsContent;
338     }
339     
340     public static boolean isExistsSdkFromIOS(String filePath, String projectName)
341     {
342         ZipFile file = null;
343         try {
344             File iosFile = new File(filePath);
345             file = new ZipFile(iosFile, 1);
346             ZipEntry entryCharge = file.getEntry("Payload/"+ projectName +"/Res.bundle/Charge.xml");
347             ZipEntry entryConsumeCode = file.getEntry("Payload/"+ projectName +"/Res.bundle/ConsumeCodeInfo.xml");
348             if (entryCharge != null && entryConsumeCode != null) {
349                 return true;
350             }
351         } catch (Exception e) {
352             e.printStackTrace();
353         } finally {
354             closeZipFile(file);
355         }
356         return false;
357     }
358     
359     public static String getSdkVersionFromIOS(String filePath, String projectName)
360     {
361         String sdkVersion = null;
362         ZipFile zipfile = null;
363         try
364         {
365             File file = new File(filePath);
366             zipfile = new ZipFile(file, 1);
367             ZipEntry config = zipfile.getEntry("Payload/"+ projectName +"/Res.bundle/CM_iOS_Config.xml");
368             if (null != config)
369             {
370                 Document doc = new SAXBuilder().build(zipfile.getInputStream(config));
371                 sdkVersion = doc.getRootElement().getChildTextTrim("SDKVersion");
372             }
373         }
374         catch (Exception e)
375         {
376             DEBUGGER.error("Failed to getSdkVersion4Ios", e);
377         }
378         finally
379         {
380             closeZipFile(zipfile);
381         }
382         return sdkVersion;
383     }
384     
385     public static String getXmlFromIOS(String filePath, String projectName)
386     {
387         ZipFile zipfile = null;
388         NSObject nsObject = null;
389         try
390         {
391             File file = new File(filePath);
392             zipfile = new ZipFile(file, 1);
393             ZipEntry entry = zipfile.getEntry("Payload/"+ projectName +"/Info.plist");
394             nsObject = PropertyListParser.parse(zipfile.getInputStream(entry));
395         }
396         catch (Exception e)
397         {
398             DEBUGGER.error("Failed to getXmlFromIOS", e);
399         }
400         finally
401         {
402             closeZipFile(zipfile);
403         }
404         return nsObject.toXMLPropertyList();
405     }
406 }

  

  

  

 1 import java.io.IOException;
 2 
 3 /**
 4  * Abstract interface for any object contained in a property list.
 5  * The names and functions of the various objects orient themselves
 6  * towards Apple's Cocoa API.
 7  * @author Daniel
 8  */
 9 public abstract class NSObject {
10 
11     public final static String NEWLINE = System.getProperty("line.separator");
12     public final static String INDENT = "\t";
13 
14     /**
15      * Generates the XML representation of the object (without XML headers or enclosing plist-tags).
16      * @param xml The StringBuilder onto which the XML representation is appended.
17      * @param level The indentation level of the object.
18      */
19     public abstract void toXML(StringBuilder xml, int level);
20 
21     /**
22      * Assigns IDs to all the objects in this NSObject subtree.
23      */
24     void assignIDs(BinaryPropertyListWriter out) {
25     out.assignID(this);
26     }
27 
28     /**
29      * Generates the binary representation of the object.
30      * @param out The output stream to serialize the object to.
31      */
32     abstract void toBinary(BinaryPropertyListWriter out) throws IOException;
33 
34     /**
35      * Generates a valid XML property list including headers using this object as root.
36      * @return The XML representation of the property list
37      */
38     public String toXMLPropertyList() {
39         StringBuilder xml = new StringBuilder("<?xml version=\"1.0\" encoding=\"UTF-8\"?>");
40         xml.append(NSObject.NEWLINE);
41         xml.append("<!DOCTYPE plist PUBLIC \"-//Apple//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/PropertyList-1.0.dtd\">");
42         xml.append(NSObject.NEWLINE);
43         xml.append("<plist version=\"1.0\">");
44         xml.append(NSObject.NEWLINE);
45     toXML(xml, 0);
46         xml.append(NSObject.NEWLINE);
47         xml.append("</plist>");
48         return xml.toString();
49     }
50 
51     protected void indent(StringBuilder xml, int level) {
52         for(int i=0;i<level;i++)
53             xml.append(INDENT);
54     }
55 }

 

  PropertyListParser.java

  1 /**
  2  * Parses any given property list
  3  * @author Daniel Dreibrodt
  4  */
  5 public class PropertyListParser {
  6 
  7     /**
  8      * Reads all bytes from an InputStream and stores them in an array, up to
  9      * a maximum count.
 10      * @param in The InputStream
 11      * @param max The maximum number of bytes to read.
 12      **/
 13     static byte[] readAll(InputStream in, int max) throws IOException {
 14     ByteArrayOutputStream buf = new ByteArrayOutputStream();
 15     while (max > 0) {
 16         int n = in.read();
 17         if (n == -1) break; // EOF
 18         buf.write(n);
 19         max--;
 20     }
 21     return buf.toByteArray();
 22     }
 23 
 24     /**
 25      * Parses a property list from a file. It can either be in XML or binary format.
 26      * @param f The property list file
 27      * @return The root object in the property list
 28      * @throws Exception If an error occurred while parsing
 29      */
 30     public static NSObject parse(File f) throws Exception {
 31         FileInputStream fis = new FileInputStream(f);
 32         String magicString = new String(readAll(fis, 8), 0, 8);
 33         fis.close();
 34         if (magicString.startsWith("bplist00")) {
 35             return BinaryPropertyListParser.parse(f);
 36         } else if (magicString.startsWith("<?xml")) {
 37             return XMLPropertyListParser.parse(f);
 38         } else {
 39             throw new UnsupportedOperationException("The given data is neither a binary nor a XML property list. ASCII property lists are not supported.");
 40         }
 41     }
 42 
 43     /**
 44      * Parses a property list from a byte array. It can either be in XML or binary format.
 45      * @param bytes The property list data
 46      * @return The root object in the property list
 47      * @throws Exception If an error occurred while parsing.
 48      */
 49     public static NSObject parse(byte[] bytes) throws Exception {
 50         String magicString = new String(bytes, 0, 8);
 51         if (magicString.startsWith("bplist00")) {
 52             return BinaryPropertyListParser.parse(bytes);
 53         } else if (magicString.startsWith("<?xml")) {
 54             return XMLPropertyListParser.parse(bytes);
 55         } else {
 56             throw new UnsupportedOperationException("The given data is neither a binary nor a XML property list. ASCII property lists are not supported.");
 57         }
 58     }
 59 
 60     /**
 61      * Parses a property list from an InputStream. It can either be in XML or binary format.
 62      * @param is The InputStream delivering the property list data
 63      * @return The root object of the property list
 64      * @throws Exception If an error occurred while parsing.
 65      */
 66     public static NSObject parse(InputStream is) throws Exception {
 67         if(is.markSupported()) {
 68             is.mark(10);
 69             String magicString = new String(readAll(is, 8), 0, 8);
 70             is.reset();
 71             if (magicString.startsWith("bplist00")) {
 72                 return BinaryPropertyListParser.parse(is);
 73             } else if (magicString.startsWith("<?xml")) {
 74                 return XMLPropertyListParser.parse(is);
 75             } else {
 76                 throw new UnsupportedOperationException("The given data is neither a binary nor a XML property list. ASCII property lists are not supported.");
 77             }
 78         } else {
 79             //Now we have to read everything, because if one parsing method fails
 80             //the whole InputStream is lost as we can't reset it
 81             return parse(readAll(is, Integer.MAX_VALUE));
 82         }
 83     }
 84 
 85     /**
 86      * Saves a property list with the given object as root into a XML file
 87      * @param root the root object
 88      * @param out the output file
 89      * @throws IOException if an error occurs during writing
 90      */
 91     public static void saveAsXML(NSObject root, File out) throws IOException {
 92     OutputStreamWriter w = new OutputStreamWriter(new FileOutputStream(out), "UTF-8");
 93         w.write(root.toXMLPropertyList());
 94         w.close();
 95     }
 96 
 97     /**
 98      * Converts a given property list file into the xml format
 99      * @param in the source file
100      * @param out the target file
101      * @throws Exception if an error occurs during parsing
102      * @throws IOException if an error occurs during writing
103      */
104     public static void convertToXml(File in, File out) throws Exception {
105         NSObject root = parse(in);
106         saveAsXML(root, out);
107     }
108     
109     /**
110      * Saves a property list with the given object as root into a binary file
111      * @param root the root object
112      * @param out the output file
113      * @throws IOException if an error occurs during writing
114      */
115     public static void saveAsBinary(NSObject root, File out) throws IOException {
116     BinaryPropertyListWriter.write(out, root);
117     }
118     
119     /**
120      * Converts a given property list file into the binary format
121      * @param in the source file
122      * @param out the target file
123      * @throws Exception if an error occurs during parsing
124      * @throws IOException if an error occurs during writing
125      */
126     public static void convertToBinary(File in, File out) throws Exception {
127     NSObject root = parse(in);
128     saveAsBinary(root, out);
129     }
130 }

 

posted @ 2016-03-16 11:04  XQiu  阅读(1316)  评论(0编辑  收藏  举报