• 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 = "	";
     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("	");
     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() - "	".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("
    ");
    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 = "	";
    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 }
  • 相关阅读:
    在vs code中进行本地调试和开启本地服务器
    按highcharts中column形式转对象展现格式
    forEach、for in 、 for of三者的区别
    一位数左边补0,slice也可以
    js判断对象是否为空
    谷歌最佳实践
    谷歌最佳实践
    谷歌最佳实践
    谷歌最佳实践
    企业代码版本管理之争:TrunkBased vs GitFlow vs AoneFlow vs OneFlow vs ExeFlow
  • 原文地址:https://www.cnblogs.com/XQiu/p/5282643.html
Copyright © 2020-2023  润新知