ios 解析zip

2019-02-23 09:10:54 ugfdfgg 阅读数 126
  • 采用全局过滤器ExceptionFilter实现AOP

    能够说出Rancher软件的作用,能够在Rancher中部署微服务 能够说出influxDB的作用,能够创建数据库、用户、赋予权限 能够说出cAdvisor 的作用,能够创建容器与influxDB连接 能够说出Grafana 的作用,能够使用Grafana...

    71人学习 田果果
    免费试看

分享一下我老师大神的人工智能教程。零基础!通俗易懂!风趣幽默!还带黄段子!希望你也加入到我们人工智能的队伍中来!https://blog.csdn.net/jiangjunshow

               

vcf, 通讯录导出的一种格式。


一。生成vcf文件

如果要把我们iPhone通讯录里的数据, 生成vcf格式文件。

我们可以借助iCloud。  

小技巧:通过iCloud导出iPhone通讯录的方法

当然, 如果你想在应用中, 利用代码生成, 完全可以。先导出通讯录数据, 再解析, 再生成vcf文件即可。

参考下面代码:

-(NSString*)generateVCardStringWithContacts:(CFArrayRef)contacts {    NSInteger counter  = 0;    NSString *vcard = @"";        for(CFIndex i = 0; i < CFArrayGetCount(contacts); i++) {                ABRecordRef person = CFArrayGetValueAtIndex(contacts, i);                NSString *firstName = (NSString*)ABRecordCopyValue(person, kABPersonFirstNameProperty);        firstName = (firstName ? firstName : @"");        NSString *lastName = (NSString *)ABRecordCopyValue(person, kABPersonLastNameProperty);        lastName = (lastName ? lastName : @"");        NSString *middleName = (NSString *)ABRecordCopyValue(person, kABPersonMiddleNameProperty);        NSString *prefix = (NSString *)ABRecordCopyValue(person, kABPersonPrefixProperty);        NSString *suffix = (NSString *)ABRecordCopyValue(person, kABPersonSuffixProperty);        NSString *nickName = (NSString *)ABRecordCopyValue(person, kABPersonNicknameProperty);        NSString *firstNamePhonetic = (NSString *)ABRecordCopyValue(person, kABPersonFirstNamePhoneticProperty);        NSString *lastNamePhonetic = (NSString *)ABRecordCopyValue(person, kABPersonLastNamePhoneticProperty);                NSString *organization = (NSString *)ABRecordCopyValue(person, kABPersonOrganizationProperty);        NSString *jobTitle = (NSString *)ABRecordCopyValue(person, kABPersonJobTitleProperty);        NSString *department = (NSString *)ABRecordCopyValue(person, kABPersonDepartmentProperty);                NSString *compositeName = [NSString stringWithFormat:@"%@%@",firstName,lastName];                if(i > 0) {            vcard = [vcard stringByAppendingFormat:@"\n"];        }                vcard = [vcard stringByAppendingFormat:@"BEGIN:VCARD\nVERSION:3.0\nN:%@;%@;%@;%@;%@\n",                 (firstName ? firstName : @""),                 (lastName ? lastName : @""),                 (middleName ? middleName : @""),                 (prefix ? prefix : @""),                 (suffix ? suffix : @"")                 ];                vcard = [vcard stringByAppendingFormat:@"FN:%@\n",compositeName];        if(nickName) vcard = [vcard stringByAppendingFormat:@"NICKNAME:%@\n",nickName];        if(firstNamePhonetic) vcard = [vcard stringByAppendingFormat:@"X-PHONETIC-FIRST-NAME:%@\n",firstNamePhonetic];        if(lastNamePhonetic) vcard = [vcard stringByAppendingFormat:@"X-PHONETIC-LAST-NAME:%@\n",lastNamePhonetic];                // Work        if(organization) vcard = [vcard stringByAppendingFormat:@"ORG:%@;%@\n",(organization?organization:@""),(department?department:@"")];                if(jobTitle) vcard = [vcard stringByAppendingFormat:@"TITLE:%@\n",jobTitle];                // Mail        ABMultiValueRef emails = ABRecordCopyValue(person, kABPersonEmailProperty);        if(emails) {            for (int k = 0; k < ABMultiValueGetCount(emails); k++) {                NSString *label = (NSString*)ABAddressBookCopyLocalizedLabel(ABMultiValueCopyLabelAtIndex(emails, k));                NSString *email = (NSString *)ABMultiValueCopyValueAtIndex(emails, k);                NSString *labelLower = [label lowercaseString];                                vcard = [vcard stringByAppendingFormat:@"EMAIL;type=INTERNET;type=WORK:%@\n",email];                                if ([labelLower isEqualToString:@"home"]) vcard = [vcard stringByAppendingFormat:@"EMAIL;type=INTERNET;type=HOME:%@\n",email];                else if ([labelLower isEqualToString:@"work"]) vcard = [vcard stringByAppendingFormat:@"EMAIL;type=INTERNET;type=WORK:%@\n",email];                else {//类型解析不出来的                    counter++;                    vcard = [vcard stringByAppendingFormat:@"item%d.EMAIL;type=INTERNET:%@\nitem%d.X-ABLabel:%@\n",counter,email,counter,label];                }            }        }                // Tel        ABMultiValueRef phoneNumbers = ABRecordCopyValue(person, kABPersonPhoneProperty);        if(phoneNumbers) {            for (int k = 0; k < ABMultiValueGetCount(phoneNumbers); k++) {                NSString *label = (NSString*)ABAddressBookCopyLocalizedLabel(ABMultiValueCopyLabelAtIndex(phoneNumbers, k));                NSString *number = (NSString *)ABMultiValueCopyValueAtIndex(phoneNumbers, k);                NSString *labelLower = [label lowercaseString];                                if ([labelLower isEqualToString:@"mobile"]) vcard = [vcard stringByAppendingFormat:@"TEL;type=CELL:%@\n",number];                else if ([labelLower isEqualToString:@"home"]) vcard = [vcard stringByAppendingFormat:@"TEL;type=HOME:%@\n",number];                else if ([labelLower isEqualToString:@"work"]) vcard = [vcard stringByAppendingFormat:@"TEL;type=WORK:%@\n",number];                else if ([labelLower isEqualToString:@"main"]) vcard = [vcard stringByAppendingFormat:@"TEL;type=MAIN:%@\n",number];                else if ([labelLower isEqualToString:@"homefax"]) vcard = [vcard stringByAppendingFormat:@"TEL;type=HOME;type=FAX:%@\n",number];                else if ([labelLower isEqualToString:@"workfax"]) vcard = [vcard stringByAppendingFormat:@"TEL;type=WORK;type=FAX:%@\n",number];                else if ([labelLower isEqualToString:@"pager"]) vcard = [vcard stringByAppendingFormat:@"TEL;type=PAGER:%@\n",number];                else if([labelLower isEqualToString:@"other"]) vcard = [vcard stringByAppendingFormat:@"TEL;type=OTHER:%@\n",number];                else { //类型解析不出来的                    counter++;                    vcard = [vcard stringByAppendingFormat:@"item%d.TEL:%@\nitem%d.X-ABLabel:%@\n",counter,number,counter,label];                }            }        }                // Address        ABMultiValueRef address = ABRecordCopyValue(person, kABPersonAddressProperty);        if(address) {            for (int k = 0; k < ABMultiValueGetCount(address); k++) {                NSString *label = (NSString*)ABAddressBookCopyLocalizedLabel(ABMultiValueCopyLabelAtIndex(label, k));                NSDictionary *dic = (NSDictionary *)ABMultiValueCopyLabelAtIndex(address, k);                NSString *labelLower = [label lowercaseString];                NSString* country = [dic valueForKey:(NSString *)kABPersonAddressCountryKey];                NSString* city = [dic valueForKey:(NSString *)kABPersonAddressCityKey];                NSString* state = [dic valueForKey:(NSString *)kABPersonAddressStateKey];                NSString* street = [dic valueForKey:(NSString *)kABPersonAddressStreetKey];                NSString* zip = [dic valueForKey:(NSString *)kABPersonAddressZIPKey];                NSString* countryCode = [dic valueForKey:(NSString *)kABPersonAddressCountryCodeKey];                NSString *type = @"";                NSString *labelField = @"";                counter++;                                if([labelLower isEqualToString:@"work"]) type = @"WORK";                else if([labelLower isEqualToString:@"home"]) type = @"HOME";                else if(label && [label length] > 0)                {                    labelField = [NSString stringWithFormat:@"item%d.X-ABLabel:%@\n",counter,label];                }                                vcard = [vcard stringByAppendingFormat:@"item%d.ADR;type=%@:;;%@;%@;%@;%@;%@\n%@item%d.X-ABADR:%@\n",                         counter,                         type,                         (street ? street : @""),                         (city ? city : @""),                         (state ? state : @""),                         (zip ? zip : @""),                         (country ? country : @""),                         labelField,                         counter,                         (countryCode ? countryCode : @"")                         ];            }        }                        // 剩下的不常用,我就不写了,要是需要,自己补全        // url        // TODO:                // IM        // TODO:                // Photo        // TODO:                vcard = [vcard stringByAppendingString:@"END:VCARD"];    }        return vcard;}



二。解析vcf文件

用  UIDocumentInteractionController  也就是用QuickLook去显示这个文件。  那他会自动的解析, 并且有添加到通讯录选项。


当然,我们也可以自己来解析。

具体代码如下: 

//解析vcf-(void)parseVCardString:(NSString*)vcardString{    NSArray *lines = [vcardString componentsSeparatedByString:@"\n"];        for(NSString* line in lines)    {                if ([line hasPrefix:@"BEGIN"])        {            NSLog(@"parse start");        }        else if ([line hasPrefix:@"END"])        {            NSLog(@"parse end");        }        else if ([line hasPrefix:@"N:"])        {            NSArray *upperComponents = [line componentsSeparatedByString:@":"];            NSArray *components = [[upperComponents objectAtIndex:1] componentsSeparatedByString:@";"];                        NSString * lastName = [components objectAtIndex:0];            NSString * firstName = [components objectAtIndex:1];                        NSLog(@"name %@ %@",lastName,firstName);                    }        else if ([line hasPrefix:@"EMAIL;"])        {            NSArray *components = [line componentsSeparatedByString:@":"];            NSString *emailAddress = [components objectAtIndex:1];            NSLog(@"emailAddress %@",emailAddress);                    }        else if ([line hasPrefix:@"TEL;"])        {            NSArray *components = [line componentsSeparatedByString:@":"];            NSString *phoneNumber = [components objectAtIndex:1];            NSLog(@"phoneNumber %@",phoneNumber);        }    }    }


           

分享一下我老师大神的人工智能教程。零基础!通俗易懂!风趣幽默!还带黄段子!希望你也加入到我们人工智能的队伍中来!https://blog.csdn.net/jiangjunshow

2015-10-08 10:46:58 ruyi366 阅读数 2793
  • 采用全局过滤器ExceptionFilter实现AOP

    能够说出Rancher软件的作用,能够在Rancher中部署微服务 能够说出influxDB的作用,能够创建数据库、用户、赋予权限 能够说出cAdvisor 的作用,能够创建容器与influxDB连接 能够说出Grafana 的作用,能够使用Grafana...

    71人学习 田果果
    免费试看


参考文档:http://my.oschina.net/heweipo/blog/382942


IOS IPA文件中包含Info.plist文件,类似于Android的AndroidManifest.xml,因此想获取IOS版本相关信息,就需要解析其Info.plist文件。参考文档中有详细的描述,但编译不过,调用的函数名搞错了,以如下代码为准。

public class IpaUtil{

    /**
     * 解压IPA文件,只获取IPA文件的Info.plist文件存储指定位置
     * @param file   zip文件
     * @param unzipDirectory     解压到的目录
     * @throws Exception
     */
    private static File getZipInfo(File file, String unzipDirectory) throws Exception{
        // 定义输入输出流对象
        InputStream input = null;
        OutputStream output = null;
        File result = null;
        File unzipFile = null;
        ZipFile zipFile = null;
        try{
            // 创建zip文件对象
            zipFile = new ZipFile(file);
            // 创建本zip文件解压目录
            String name = file.getName().substring(0, file.getName().lastIndexOf("."));
            unzipFile = new File(unzipDirectory + "/" + name);
            if(unzipFile.exists()){
                unzipFile.delete();
            }
            unzipFile.mkdir();
            // 得到zip文件条目枚举对象
            Enumeration<? extends ZipEntry> zipEnum = zipFile.entries();
            // 定义对象
            ZipEntry entry = null;
            String entryName = null;
            String names[] = null;
            int length;
            // 循环读取条目
            while(zipEnum.hasMoreElements()){
                // 得到当前条目
                entry = zipEnum.nextElement();
                entryName = new String(entry.getName());
                // 用/分隔条目名称
                names = entryName.split("\\/");
                length = names.length;
                for(int v = 0; v < length; v++){
                    if(entryName.endsWith(".app/Info.plist")){ // 为Info.plist文件,则输出到文件
                        input = zipFile.getInputStream(entry);
                        result = new File(unzipFile.getAbsolutePath() + "/Info.plist");
                        output = new FileOutputStream(result);
                        byte[] buffer = new byte[1024 * 8];
                        int readLen = 0;
                        while((readLen = input.read(buffer, 0, 1024 * 8)) != -1){
                            output.write(buffer, 0, readLen);
                        }
                        break;
                    }
                }
            }
        }
        catch(Exception ex){
            ex.printStackTrace();
        }
        finally{
            if(input != null){
                input.close();
            }
            if(output != null){
                output.flush();
                output.close();
            }
            // 必须关流,否则文件无法删除
            if(zipFile != null){
                zipFile.close();
            }
        }
        
        // 如果有必要删除多余的文件
        if(file.exists()){
            file.delete();
        }
        return result;
    }

    /**
     * IPA文件的拷贝,把一个IPA文件复制为Zip文件,同时返回Info.plist文件 参数 oldfile 为 IPA文件
     */
    private static File getIpaInfo(File oldfile) throws IOException{
        try{
            int byteread = 0;
            String filename = oldfile.getAbsolutePath().replaceAll(".ipa", ".zip");
            File newfile = new File(filename);
            if(oldfile.exists()){
                // 创建一个Zip文件
                InputStream inStream = new FileInputStream(oldfile);
                FileOutputStream fs = new FileOutputStream(newfile);
                byte[] buffer = new byte[1444];
                while((byteread = inStream.read(buffer)) != -1){
                    fs.write(buffer, 0, byteread);
                }
                if(inStream != null){
                    inStream.close();
                }
                if(fs != null){
                    fs.close();
                }
                // 解析Zip文件
                return getZipInfo(newfile, newfile.getParent());
            }
        }
        catch(Exception e){
            e.printStackTrace();
        }
        return null;
    }

    /**
     * 通过IPA文件获取Info信息
     */
    public static Map<String, String> getVersionInfo(File ipa) throws Exception{

        File file = getIpaInfo(ipa);
	Map<String,String> map = new HashMap<String,String>();
	// 需要第三方jar包dd-plist 
	NSDictionary rootDict = (NSDictionary)PropertyListParser.parse(file); 
	// 应用包名 NSString parameters = (NSString)rootDict.objectForKey("CFBundleIdentifier"); 
	map.put("CFBundleIdentifier", parameters.toString()); 
	// 应用名称 NSString parameters = (NSString)rootDict.objectForKey("CFBundleName");
        map.put("CFBundleName", parameters.toString());
	// 应用版本 parameters = (NSString)rootDict.objectForKey("CFBundleVersion");
        map.put("CFBundleVersion", parameters.toString());
	// 应用展示的名称 parameters = (NSString)rootDict.objectForKey("CFBundleDisplayName"); 
	map.put("CFBundleDisplayName", parameters.toString()); 
	// 应用所需IOS最低版本 parameters = (NSString)rootDict.objectForKey("MinimumOSVersion"); 
	map.put("MinimumOSVersion", parameters.toString()); 

	// 如果有必要,应该删除解压的结果文件
	file.delete(); 
	file.getParentFile().delete(); 
				
	return info; 
    }
}





如果用Maven,可以在pom文件中加入如下xml,获取到第三方包dd-plist:

<dependency>
	<groupId>com.googlecode.plist</groupId>
	<artifactId>dd-plist</artifactId>
	<version>1.16</version>
</dependency>
如果想直接获取到此jar包,可以在此处下载:http://download.csdn.net/detail/ruyi366/9149741



2014-01-27 13:21:11 ifumu2011 阅读数 1802
  • 采用全局过滤器ExceptionFilter实现AOP

    能够说出Rancher软件的作用,能够在Rancher中部署微服务 能够说出influxDB的作用,能够创建数据库、用户、赋予权限 能够说出cAdvisor 的作用,能够创建容器与influxDB连接 能够说出Grafana 的作用,能够使用Grafana...

    71人学习 田果果
    免费试看

- -(void) unZipClick {

   NSString *filename = unEncodingURL;

   NSFileManager *fileManager = [NSFileManagerdefaultManager];

   if ([fileManagerfileExistsAtPath:filename])   {

       ZipArchive*zip = [[ZipArchive alloc] init];

          BOOLresult;

         if ([zip UnzipOpenFile:filename]) {

          result = [zipUnzipFileTo:[filename          stringByDeletingPathExtension]overWrite:YES];

          if (!result) {

             [zipping dismissWithClickedButtonIndex:0animated:YES];

          }

          else

          {

             NSMutableArray *arry = [[NSMutableArray alloc]initWithArray:[zip.zipPath pathComponents]];

             if (![[[arry lastObject] pathExtension]isEqualToString:@""]) {

                 [arryremoveLastObject];

             }

             [arry removeObject:@"__MACOSX"];

             NSMutableString * sendString = [[NSMutableString                 alloc] init];

             BOOL isFirst = YES;

             for (NSString *dd in arry) {

                 if(isFirst) {

                    [sendStringsetString:dd];

                    isFirst = NO;

                }

                else

                {

                    [sendStringappendString:dd];

                    [sendStringappendString:@"/"] ;

                }

             }

             filePath = [[NSMutableString alloc]initWithString:sendString];

             [self showDirView];//此处是我利用filePath去获取刚才解压好的                             文件目录下的所有文件

         }

          [zipUnzipCloseFile];

      }

      else

      {

          [zippingdismissWithClickedButtonIndex:0 animated:YES];

          UIAlertView *zipping =[[UIAlertView alloc] initWithTitle:@"解压失败"message:@"文件损坏或者格式暂时无法解析"delegate:self cancelButtonTitle:@"知道了"otherButtonTitles: nil];

          [zipping show];

          

      }

   }


}

zip相对比较简单,demo也不少,所以不做过多描述

2.RAR解压

之前已知没有好的办法,昨天去发现了Unrar4ios然后download下来看了看,地址https://github.com/ararog/Unrar4iOS
上面的那个zip下载下来后,网站里面有说明文档,zip包里有两个工程,一个是Unrar4iOS,一个是UnrarExample,前者是静态类库,需要自己编译,此处不多说了,后者就是网站给出的demo,不过其中还是存在点问题。
运行后会发现有错误
提示无法找到"RARExtractException.h"文件,此时你需要在unrar4iOS包中去找,然后将它添加到现有的这个demo中
此外unrar4ios.mm 也要倒入到工程中
此文件中是实现文件,rar解析的方法出自此处,如果步导入这个文件,你会发现,在你运行demo的时候,rar解析的几个方法不能按预期进行

-(BOOL) unrarOpenFile:(NSString*) rarFile;

-(BOOL) unrarOpenFile:(NSString*) rarFile withPassword:(NSString*)aPassword;

-(NSArray *) unrarListFiles;

-(BOOL) unrarFileTo:(NSString*) path overWrite:(BOOL)overwrite;

-(NSData *) extractStream:(NSString *)aFile;

-(BOOL)unrarCloseFile;  
这几个方法就是rar解压时所用到的主要的几个方法,看方法名就应该知道时干嘛的了


ps:1.如果在解压rar时遇到了不能兼容armv7s的情况,参照上篇博客
    2.由于时间关系,没有写的更详细点,特别是解压的时候,路径,文件涉及到的编码问题
2016-09-22 16:31:38 elsonpeng 阅读数 3805
  • 采用全局过滤器ExceptionFilter实现AOP

    能够说出Rancher软件的作用,能够在Rancher中部署微服务 能够说出influxDB的作用,能够创建数据库、用户、赋予权限 能够说出cAdvisor 的作用,能够创建容器与influxDB连接 能够说出Grafana 的作用,能够使用Grafana...

    71人学习 田果果
    免费试看

项目需要,最近处理zip包中的文件,经探索有两种方式,分别对应的类库文件为:ZipArchive 和 Objective-Zip。对应的下载地址分别为:

(1)http://ziparchive.googlecode.com/files/ZipArchive.zip

 没法FQ的小伙伴可以去http://download.csdn.net/detail/xiaodragon2008/9621450下载即可

(2)https://github.com/gianlucabertani/Objective-Zip

这两个开源库都具备压缩,和解压缩功能,下面只介绍自己用到的读取Zip包中的功能

1.ZipArchive

这个方法需要首先将压缩包解压到某个目录,然后再从解压到的目录中去读取相应的文件即可,首先引入下载地址中的第三方库文件

下面代码实现的操作是读取本地项目中的20160809.zip包中的文件,解压以后并读取20160809.xml中的文件

NSString *zipPath = [[NSBundle mainBundle] pathForResource:@"20160809" ofType:@"zip"];
     
    NSLog(@" zip path :%@",zipPath);
    ZipArchive *za = [[ZipArchive alloc]init];
     
    NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
    NSString *documentpath = ([paths count] > 0) ? [paths objectAtIndex:0] : nil;
    <br>NSFileManager *fileManager = [NSFileManager defaultManager];
    NSString *unzipFilePath = [documentpath stringByAppendingPathComponent:@"/test"];
     
    if([za UnzipOpenFile:zipPath])
    {
        BOOL ret = [za UnzipFileTo:unzipFilePath overWrite:YES];
        if(ret == NO){
             
        }
        [za UnzipCloseFile];
    }
     
    NSString *unzipFullPath = [NSString stringWithFormat:@"%@/20160809.xml",unzipFilePath];
    NSData *xmlData = [NSData dataWithContentsOfFile:unzipFullPath options:0 error:nil];
    NSDictionary *responseData = [NSDictionary dictionaryWithXMLData:xmlData];



2.Objective-Zip 该方法,可以解压后读取,也可以直接解压到内存中读取,本人为了提高效率,主要采用后面一种处理方式

NSString *zipPath = [[NSBundle mainBundle] pathForResource:@"20160809" ofType:@"zip"];
 
    NSError *error;
    OZZipFile *unzipFile = [[OZZipFile alloc]initWithFileName:zipPath mode:OZZipFileModeUnzip error:&error];
    if(error != nil)
    {
        return;
    }
    NSLog(@"error -- xx %@",error);
//    OZZipFile *unzipFile= [[OZZipFile alloc] initWithFileName:zipPath
//                                                         mode:OZZipFileModeUnzip];
     
    [unzipFile goToFirstFileInZip];
    OZFileInZipInfo *info= [unzipFile getCurrentFileInZipInfo];
     
    OZZipReadStream *read= [unzipFile readCurrentFileInZip];
    NSMutableData *data= [[NSMutableData alloc] initWithLength:info.length];
    [read readDataWithBuffer:data];
     
    // Do something with data
    NSData *xmlData = [NSData dataWithData:data];
    NSDictionary *responseData = [NSDictionary dictionaryWithXMLData:xmlData];
    NSLog(@"responseData %@",responseData);
    [read finishedReading];

注意,为了保证有时候读取的文件有可能不是zip文件,所以要做容错处理,要使用

OZZipFile *unzipFile = [[OZZipFile alloc]initWithFileName:zipPath mode:OZZipFileModeUnzip error:&error];
    if(error != nil)
    {
        return;
    }<br>而不是如下的初始化zip包文件方法。
OZZipFile *unzipFile= [[OZZipFile alloc] initWithFileName:zipPath mode:OZZipFileModeUnzip];

比如说我曾经遇到过,从服务器中去下载zip包文件,但是出现过下载到本地的zip包文件无法打开,因为服务器给返回的是http请求是200但是没有数据,给我返回一个resultcode,导致程序没法解压该zip包文件,app意外崩溃。

2016-03-16 11:07:00 weixin_33840661 阅读数 31
  • 采用全局过滤器ExceptionFilter实现AOP

    能够说出Rancher软件的作用,能够在Rancher中部署微服务 能够说出influxDB的作用,能够创建数据库、用户、赋予权限 能够说出cAdvisor 的作用,能够创建容器与influxDB连接 能够说出Grafana 的作用,能够使用Grafana...

    71人学习 田果果
    免费试看
  1 import java.io.BufferedInputStream;
  2 import java.io.File;
  3 import java.io.FileInputStream;
  4 import java.io.IOException;
  5 import java.io.InputStream;
  6 import java.io.StringReader;
  7 import java.util.ArrayList;
  8 import java.util.HashMap;
  9 import java.util.List;
 10 import java.util.zip.ZipEntry;
 11 import java.util.zip.ZipFile;
 12 import java.util.zip.ZipInputStream;
 13 
 14 import org.apache.commons.lang.StringUtils;
 15 import org.apache.poi.util.IOUtils;
 16 import org.dom4j.Document;
 17 import org.dom4j.DocumentException;
 18 import org.dom4j.Element;
 19 import org.dom4j.io.SAXReader;
 20 import org.w3c.dom.Node;
 21 import org.xml.sax.InputSource;
 22 
 23 
 24 /**
 25  * IOS文件解析
 26  * 
 27  * @author     dKF63325
 28  * @version    ONIP BME V300R001 2014-6-9
 29  * @since      ONIP BME V300R001C00
 30  */
 31 public class IosInfoUtils
 32 {
 33 
 34     
 35     public static HashMap<String, Object> getIosInfo(String filePath, String fileName) throws Exception
 36     {
 37         // 获得二级目录名称
 38         String appName = getAppName(filePath);
 39         
 40         // 解析文件
 41         HashMap<String, Object> infoMap = parseXml(filePath, appName);
 42         
 43         File file = new File(filePath);
 44         // 文件名称
 45         infoMap.put("fileName", file.getName());
 46         // 文件大小
 47         infoMap.put("fileSize", convertFileSize(file.length()));
 48         // 文件大小(单位:字节)
 49         infoMap.put("fileByteSize", file.length());
 50         // 是否存在SDK
 51         infoMap.put("isSDK", AXMLPrinter2.isExistsSdkFromIOS(filePath, appName));
 52         // SDK版本号
 53         infoMap.put("sdkVersion", AXMLPrinter2.getSdkVersionFromIOS(filePath, appName));
 54 
 55         return infoMap;
 56     }
 57     
 58     private static String getAppName(String filePath)
 59     {
 60         ZipFile file = null;
 61         InputStream in = null;
 62         String name = StringUtils.EMPTY;
 63         try
 64         {
 65             in = new BufferedInputStream(new FileInputStream(filePath));
 66             ZipInputStream zip = new ZipInputStream(in);
 67             ZipEntry zp = null;
 68             while ((zp = zip.getNextEntry()) != null)
 69             {
 70                 name = zp.getName();
 71                 if (name.indexOf(".app") != -1)
 72                 {
 73                     name = name.substring(name.indexOf("Payload/")+"Payload/".length(), name.indexOf(".app") + ".app".length());
 74                     break;
 75                 }
 76             }
 77         }
 78         catch (IOException e)
 79         {
 80             DEBUGGER.error("Failed to getAppName", e);
 81         }
 82         finally
 83         {
 84             IOUtils.closeQuietly(in);
 85             AXMLPrinter2.closeZipFile(file);
 86         }
 87         return name;
 88     }
 89 
 90     private static HashMap<String, Object> parseXml(String filePath, String projectName) throws IOException, Exception, DocumentException
 91     {
 92         String xml = AXMLPrinter2.getXmlFromIOS(filePath, projectName);
 93         StringReader read = new StringReader(xml);
 94         InputSource scource = new InputSource(read);
 95         SAXReader sax = new SAXReader();
 96         sax.setFeature("http://apache.org/xml/features/nonvalidating/load-external-dtd", false);
 97         Document root = sax.read(scource);
 98         Element dictElement = (Element) root.selectSingleNode("//dict");
 99         List<Element> children = filterElement(dictElement.elements());
100         HashMap<String, Object> infoMap = new HashMap<String, Object>();
101         for (int i = 0; i < children.size(); i+=2)
102         {
103             Element key = children.get(i);
104             Element val = children.get(i+1);
105             if ("array".equals(val.getName()))
106             {
107                 List<Element> arrayList = filterElement(val.elements());
108                 String values = StringUtils.EMPTY;
109                 for (Element element : arrayList)
110                 {
111                     values += element.getStringValue() + ",";
112                 }
113                 infoMap.put(key.getStringValue(), StringUtils.removeEnd(values, ","));
114             } else if ("true".equals(val.getName())) {
115                 infoMap.put(key.getStringValue(), true);
116             } else if ("false".equals(val.getName())) {
117                 infoMap.put(key.getStringValue(), false);
118             } else {
119                 infoMap.put(key.getStringValue(), val.getStringValue());
120             }
121         }
122         return infoMap;
123     }
124     
125     private static List<Element> filterElement(List<?> elements) {
126         List<Element> result = new ArrayList<Element>(elements.size());
127         for (Object object : elements)
128         {
129             Element element = (Element)object;
130             if (element.getNodeType() == Node.ELEMENT_NODE)
131             {
132                 result.add(element);
133             }
134         }
135         return result;
136     }
137     
138     public static String convertFileSize(long filesize)
139     {
140         String strUnit = "Bytes";
141         String strAfterComma = "";
142         int intDivisor = 1;
143         if (filesize >= 1024 * 1024)
144         {
145             strUnit = "MB";
146             intDivisor = 1024 * 1024;
147         } else if (filesize >= 1024)
148         {
149             strUnit = "KB";
150             intDivisor = 1024;
151         }
152         if (intDivisor == 1){
153             return filesize + " " + strUnit;
154         }
155 
156         strAfterComma = "" + 100 * (filesize % intDivisor) / intDivisor;
157         if (strAfterComma.equals(""))
158             strAfterComma = ".0";
159         
160         return filesize / intDivisor + "." + strAfterComma + " " + strUnit;
161     }
162 }

 

转载于:https://www.cnblogs.com/XQiu/p/5282658.html