iOS 资源文件的解压缩与加解密

一、目的

  一般来说,资源文件或者是很多(图片),或者是很大(视频)。这样很是占空间或者上看去很多内容,当然如果你想这样做完全没有问题。

  解压缩可以很好的压缩 多资源 和 大资源,让包体变小,同一套资源有些许改变,压缩后文件的md5也不同。加密是让压缩包不能正常解压,看上去是损坏了的。

二、解压缩

  解压缩使用的是第三方 ZipArchive 库,个人进行了封装,直接上源码。

  压缩:需要注意的点在注释中说明了。

/*!
 * 压缩 单个文件 或 单个文件夹
 * eg: demo.txt    ==> demo.txt.zip
 *     demo.bundle ==> demo.bundle.zip
 * @param filePath 单个文件 或 单个文件夹 路径
 * @return 是否压缩成功
 */
+ (BOOL)wy_archiveFileAtPath:(NSString *)filePath {
    
    NSFileManager *fm = [NSFileManager defaultManager];
    BOOL isDir;
    if (![fm fileExistsAtPath:filePath isDirectory:&isDir]) {
        NSLog(@"要压缩的文件(夹) %@ 不存在", filePath);
        return NO;
    }
    
    NSString *zipPath = [filePath stringByAppendingPathExtension:@"zip"];
    ZipArchive *zipArchive = [[ZipArchive alloc] initWithFileManager:fm];
    BOOL ret = [zipArchive CreateZipFile2:zipPath];
    if (!ret) {
        NSLog(@"创建 zip 失败");
        return NO;
    }
    
    if (isDir) {// 文件夹 demo.bundle ==> demo.bundle.zip
        // 注意:文件夹时 不要使用 contentsOfDirectoryAtPath 遍历, 列出所有的文件和子目录。
        // 问题是子目录会被压缩成武后缀的文件,而不是被当做文件夹处理
        // 调用 subpathsAtPath 会列出 filePath 下的所有文件和子目录
        NSArray *subPaths = [fm subpathsAtPath:filePath];
        for (NSString *subPath in subPaths) {
            NSString *fullPath = [filePath stringByAppendingPathComponent:subPath];
            isDir = NO;
            if ([fm fileExistsAtPath:fullPath isDirectory:&isDir] && !isDir) {// 不处理文件夹
                [zipArchive addFileToZip:fullPath newname:subPath];// 注意: newname 是相对 zip 的路径
            }
        }
    } else {// 文件 demo.txt ==> demo.txt.zip
        [zipArchive addFileToZip:filePath newname:filePath.lastPathComponent];
    }
    
    if (![zipArchive CloseZipFile2]) {
        NSLog(@"压缩 zip 失败");
        return NO;
    }
    
    NSLog(@"压缩 zip 成功");
    
    return YES;
}

  解压:

/*!
 * 解压压缩文件
 * eg: demo.txt.zip    ==> demo.txt
 *     demo.bundle.zip ==> demo.bundle
 * @param aZipPath zip文件路径
 * @return 是否解压成功
 */
+ (BOOL)wy_unarchiveFileAtPath:(NSString *)aZipPath {
    
    NSFileManager *fm = [NSFileManager defaultManager];
    if (![fm fileExistsAtPath:aZipPath]) {
        NSLog(@"要解压的文件 %@ 不存在", aZipPath);
        return NO;
    }
    
    NSString *unzipPath = [aZipPath stringByDeletingPathExtension];
    ZipArchive *zipArchive = [[ZipArchive alloc] init];
    
    if ([zipArchive UnzipOpenFile:aZipPath]) {
        BOOL ret = [zipArchive UnzipFileTo:unzipPath overWrite:YES];// 覆盖解压
        if (!ret) {
            NSLog(@"解压 zip 失败");
            return NO;
        }
        [zipArchive UnzipCloseFile];
    }
    
    NSLog(@"解压 zip 成功");
    
    return YES;
}

三、加解密

  采用异或加密进行简单的加解密。

四、常见问题

  1. macOS zip 无法解压 或者 解压成 cpgz 死循环

    可能原因:

      1)zip 文件确实已经损坏;

      2) zip 文件下载不完全或出错;

      3)bug 导致;

    解压缩或加密代码原因:

      1)创建了 zip 但没有压缩资源进去 空 zip 无法解压;(那就添加资源)

      2) 压缩出错导致无法解压;(重新操作)

      3) 压缩包数据是加密了的;(需要正常解密才能解压)

    可以使用命令行 unzip zip_path 查看错误原因,以便分析问题所在。

  2. 压缩 bundle 资源文件夹

    bundle 本质是文件夹,所以压缩的时候是以文件夹压缩的,这点需要特别注意,具体看上文源码注释,很详细了。

五、使用场景

  一般是 使用前对资源的处理 资源 - 压缩 - 加密 - 加密后的资源包(无法正常解压)。

  使用时 加密后的资源 - 解密 - 解压 - 拿对应的要使用的资源 - 删除解压后的文件(夹) 这个有点耗性能。

[WYZipArchiveUtil wy_archiveFileAtPath:source];
[WYZipArchiveUtil wy_xorEncriptFileAtPath:zipPath];
[WYZipArchiveUtil wy_xorEncriptFileAtPath:zipPath]; [WYZipArchiveUtil wy_unarchiveFileAtPath:zipPath];

  

时常一个人发呆,看到宁静的天空。
原文地址:https://www.cnblogs.com/pinweyshg/p/8981712.html