一、目的
一般来说,资源文件或者是很多(图片),或者是很大(视频)。这样很是占空间或者上看去很多内容,当然如果你想这样做完全没有问题。
解压缩可以很好的压缩 多资源 和 大资源,让包体变小,同一套资源有些许改变,压缩后文件的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];