一、LzmaSDKObjC
项目地址: gitcode.com/gh_mirrors/…
今天,我们将深入探讨一个虽已停更但技术价值不减的神器——LzmaSDKObjC,并引导您了解其继任者 PLzmaSDK。让我们一起揭示这一库如何为iOS和Mac OS平台带来无与伦比的文件处理能力。
1. 项目目录结构及介绍
LzmaSDKObjC,基于最新的C++版[LZMA SDK] v19.00开发,专为突破传统C语言接口限制而设计。它不仅支持Swift和Objective-C,更为Apple平台带来了全面的7z格式处理功能,从基础的读取到复杂的加密操作,一应俱全。虽然该库已不再更新,但它所奠定的技术基石依然强大,并被后续的 PLzmaSDK 继承发扬光大。
LzmaSDKObjC 的核心在于其对C++ LZMA SDK的高度优化集成,为移动设备量身打造。它针对iOS和Mac OS进行了特别的适配与补丁,确保了在这些平台上运行的流畅性和稳定性。该库支持广泛的7z档案操作,包括但不限于加密与解密、分块读写,以及内存管理优化,实现了低至500KB的运行内存占用,极大提升了性能和用户体验。
LzmaSDKObjC 是一个基于 Objective-C 的 LZMA 压缩库封装,旨在简化 iOS 和 macOS 应用中的压缩和解压缩操作。下面是其主要目录结构及其简介:
- LzmaSDKObjC: 核心源码包,包含所有必要的 Objective-C 类和接口。
- LzmaDecode.h/implementation.m: 解压缩相关的实现。
- LzmaEncode.h/implementation.m: 压缩相关的实现。
- Example: 示例应用目录,提供了一个简单的实例来演示如何在实际项目中使用该 SDK。
- AppDelegate.m/h: 应用的启动和配置点。
- ViewController.m/h: 展示使用 LzmaSDKObjC 进行压缩和解压的基本流程。
- LICENSE: 许可证文件,说明了该项目的授权方式(通常是 MIT 或 Apache 等开源协议)。
- README.md: 项目快速入门和基本说明文档。
2. 项目的启动文件介绍
在本项目中,启动主要由两部分构成:一个是 Xcode 中的主入口 AppDelegate, 另一部分是示例工程内的 ViewController。
-
AppDelegate.m/h: 此文件负责应用的生命周期管理,包括启动时的初始化工作,但它不直接涉及 LzmaSDKObjC 的核心功能。这是应用启动的起点,进行一些基础配置如窗口创建等。
-
示例启动逻辑位于 ViewController.m/h,在这里,开发者可以找到如何初始化 LzmaSDKObjC 实例并调用相关方法进行数据压缩和解压的示例代码。这是理解如何集成 LzmaSDKObjC 到自己项目的关键。
3. 项目的配置文件介绍
对于 LzmaSDKObjC 这样的库,其主要的“配置”通常体现在集成过程中,而不是通过传统意义上的配置文件。不过,有几个关键步骤需要注意:
- Podfile (若使用 CocoaPods): 如果选择通过 CocoaPods 来管理依赖,你的 Podfile 应该包含一行 pod 'LzmaSDKObjC' 来添加此库作为依赖。
- Build Settings: 在将 LzmaSDKObjC 集成到项目之后,可能需要调整 Build Settings 中的搜索路径或链接库设置,以确保编译器能找到对应的头文件和链接库。
4. 应用场景
此库尤其适用于需要在移动设备上处理大量数据的应用场景,如云存储同步、邮件附件处理、或是大型游戏资源的压缩与快速加载。无论是开发者需要创建支持密码保护的下载包,还是用户希望安全高效地传输私人文件,LzmaSDKObjC 都提供了强大的技术支持。
对于那些致力于保持数据隐私和提高应用内数据交换效率的开发者来说,其加密及加密头部功能至关重要,能够确保数据即使在未授权访问时也难以解读,非常适合于实现私有文件分享和云端备份应用。
5. 项目亮点
- 全方位7z支持:无论是标准的7z文件还是加密、隐藏头信息的高级安全性文件,都能轻松管理。
- 跨语言兼容性:无缝对接Swift与Objective-C,降低应用开发的技术门槛。
- 性能调优:动态调整内存与I/O操作策略,最小化资源消耗,提升速度与响应时间。
- 大文件处理:支持超过4GB的大文件操作,满足大数据时代的需求。
- UTF8编码支持,确保国际化文件名的正确处理。
- 易用性:详尽的示例代码,让快速上手成为可能。
尽管 LzmaSDKObjC 已经进入维护状态,但其技术和经验已被 PLzmaSDK 继承和发展,继续服务于iOS与Mac开发社区。对于寻找稳定、高效且安全的文件压缩解决方案的开发者来说,探索或迁移至 PLzmaSDK 无疑是一个明智的选择。
示例:
- (BOOL)decompress7z{
NSLog(@"_filePath: %@", _filePath);
NSLog(@"_destinationPath: %@", _destinationPath);
// LzmaSDKObjCReader *reader = [[LzmaSDKObjCReader alloc] initWithFileURL:[NSURL fileURLWithPath:_filePath]];
// 1.2 Or create with predefined archive type if path doesn't containes suitable extension
LzmaSDKObjCReader *reader = [[LzmaSDKObjCReader alloc] initWithFileURL:[NSURL fileURLWithPath:_filePath] andType:LzmaSDKObjCFileType7z];
// // Optionaly: assign weak delegate for tracking extract progress.
// reader.delegate = self;
// If achive encrypted - define password getter handler.
// NOTES:
// - Encrypted file needs password for extract process.
// - Encrypted file with encrypted header needs password for list(iterate) and extract archive items.
reader.passwordGetter = ^NSString*(void){
// return @"password to my achive";
NSLog(@"self.password: %@", self.password);
return self.password;
};
// Open archive, with or without error. Error can be nil.
NSError * error = nil;
if (![reader open:&error]) {
NSLog(@"Open error: %@", error);
}
NSLog(@"Open error: %@", reader.lastError);
NSMutableArray *filePathsArray = [NSMutableArray array];
NSMutableArray * items = [NSMutableArray array]; // Array with selected items.
// Iterate all archive items, track what items do you need & hold them in array.
[reader iterateWithHandler:^BOOL(LzmaSDKObjCItem * item, NSError * error){
// NSLog(@"\nitem:%@", item);
if (item) {
[items addObject:item]; // if needs this item - store to array.
if (!item.isDirectory) {
NSString *filePath = [_destinationPath stringByAppendingPathComponent:item.directoryPath];
filePath = [filePath stringByAppendingPathComponent:item.fileName];
[filePathsArray addObject:filePath];
}
}
return YES; // YES - continue iterate, NO - stop iteration
}];
NSLog(@"Iteration error: %@", reader.lastError);
// Extract selected items from prev. step.
// YES - create subfolders structure for the items.
// NO - place item file to the root of path(in this case items with the same names will be overwrited automaticaly).
[reader extract:items
toPath:_destinationPath
withFullPaths:YES];
NSLog(@"Extract error: %@", reader.lastError);
// Test selected items from prev. step.
[reader test:items];
NSLog(@"test error: %@", reader.lastError);
if (reader.lastError || ![filePathsArray count]) {
return NO;
}
else {
return YES;
}
}
- (void)testLZMA {
NSString *sourceFilePath = [NSString stringWithFormat:@"%@/source_data.txt", SYSTEM_DOCUMENT_PATH];
NSString *zipFilePath = [NSString stringWithFormat:@"%@/compressed_data.7z", SYSTEM_DOCUMENT_PATH];
DDLogDebug(@"\n\n ********** LZMA ********** \nSrc File: %@\n7Zip File:%@\n\n", sourceFilePath, zipFilePath);
// Create writer
LzmaSDKObjCWriter * writer = [[LzmaSDKObjCWriter alloc] initWithFileURL:[NSURL fileURLWithPath:zipFilePath]];
// Add file data's or paths
// [writer addData:[NSData ...] forPath:@"MyArchiveFileName.txt"]; // Add file data
[writer addPath:sourceFilePath forPath:@"."]; // Add file at path
// [writer addPath:@"/Path/SomeDirectory" forPath:@"SomeDirectory"]; // Recursively add directory with all contents
// Setup writer
writer.delegate = self; // Track progress
// writer.passwordGetter = ^NSString*(void) { // Password getter
// return @"1234";
// };
// Optional settings
writer.method = LzmaSDKObjCMethodLZMA; // or LzmaSDKObjCMethodLZMA
writer.solid = YES;
writer.compressionLevel = 7;
writer.encodeContent = YES;
writer.encodeHeader = YES;
writer.compressHeader = YES;
writer.compressHeaderFull = YES;
writer.writeModificationTime = NO;
writer.writeCreationTime = NO;
writer.writeAccessTime = NO;
// Open archive file
NSError * error = nil;
[writer open:&error];
// Write archive within current thread
[writer write];
}
二、PLzmaSDK
项目地址: github.com/OlehKulykov…
通过CocoaPods集成:
CocoaPods Podfile (Swift):
use_frameworks!
platform :ios, '11.0'
target '<REPLACE_WITH_YOUR_TARGET>' do
pod 'PLzmaSDK', '1.5.0'
end
CocoaPods Podfile (Objective-C):
use_frameworks!
platform :ios, '9.0'
target '<REPLACE_WITH_YOUR_TARGET>' do
pod 'PLzmaSDK-ObjC', '1.5.0'
end
示例:
#import <PLzmaSDK/PLzmaSDK.h>
// 初始化解压对象
PLzmaSDK *lzma = [[PLzmaSDK alloc] init];
// 设置解压后文件存放的路径
NSString *outputPath = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES).lastObject stringByAppendingPathComponent:@"output_folder"];
// 设置压缩文件的路径
NSString *archivePath = [[NSBundle mainBundle] pathForResource:@"example" ofType:@"7z"];
// 解压文件
[lzma extractArchiveAtPath:archivePath toPath:outputPath withPassword:nil completion:^(NSError * _Nullable error) {
if (error) {
NSLog(@"解压失败: %@", error);
} else {
NSLog(@"解压成功,文件解压到: %@", outputPath);
}
}];