LZMA SDK使用太多RAM解压缩iOS(xcode)
我想在iPhone / iPad应用程序中使用LZMA SDK,我的出发点是Mo Dejong提供的LZMA iPhone示例项目,可在此处获取:
https://github.com/jk/lzmaSDK 原文在这里: http://www.modejong.com/iOS/lzmaSDK.zip (我试过了两次,我从两者得到了相同的结果). 问题是提取使用的内存与.7z包含未压缩的RAM一样多.换句话说,假设我有一个40MB的压缩文件,未压缩的文件是一个大约250MB的二进制sqlite DB,它将慢慢耗尽越来越多的内存,因为它将文件解压缩到250MB.在iPhone4(256MB RAM)之前,这会使iPad1或任何东西崩溃.我有一种感觉很多人最终会遇到同样的问题,所以现在解决方案可以帮助很多开发人员. 我最初使用基于Windows的7-zip(最新版本)和16MB字典大小在PC上创建.7z文件.它应该只需要18MB的RAM来解压缩(在PC上查看任务管理器时就是这种情况).我也尝试使用keka(开源mac archiver)创建存档,它没有解决任何问题,虽然我可以确认keka本身在Mac上提取文件时只使用19MB的ram,这是我所期望的.我想下一步是将Keka的源代码与LZMA SDK的源代码进行比较. 在创建.7z文件时,我使用不同的字典大小和其他设置,但没有任何帮助.我还尝试在压缩之前将我的单个二进制文件拆分为24个较小的部分,但这也没有帮助(仍然使用超过250MB的RAM来提取24个部分). 请注意,我对原始代码所做的唯一更改是使用更大的.7z文件.另请注意,一旦提取完成,它会立即释放RAM,但这没有用.我觉得它不会释放RAM,因为它提取它应该如此,或者它将整个内容放入RAM直到最后完成并且只是将它移出RAM.此外,如果我尝试使用mac应用程序提取相同的文件,在运行仪器时,我看不到相同的行为(StuffIt Expander例如在提取文件时最大约为60MB RAM,Keka,开源mac archiver最大容量为19MB RAM). 我不是一个mac / xcode / objective-c开发人员(还),所以对此的任何帮助将不胜感激.我可以使用zip或rar代替,但是我用LZMA得到了更好的压缩,所以如果可能的话我想坚持使用这个解决方案,但显然我需要让它工作而不会崩溃. 谢谢! 解决方法
7zip的作者Igor Pavlov给我发了电子邮件,他基本上说我在原始问题中所做的观察是对c版本SDK的一个已知限制. C版本没有此限制.实际报价:
“7-Zip使用另一个用C编写的多线程解码器.C.7z解码器不需要为整个实体块分配RAM块.另请阅读此线程: http://sourceforge.net/projects/sevenzip/forums/forum/45797/topic/5655623 因此,在有人修复SDK for iOS之前,解决方法是: 1)确定要对文件解压缩操作使用的RAM限制. 2)存档中任何超过上述限制的SINGLE文件必须拆分,您可以使用任何二进制拆分器应用程序(如拆分)执行此操作: 3)文件准备好后,使用MoDJ在他的答案中描述的字典/块大小选项创建7z文件,例如24 meg限制: 4)在iOS应用程序中,解压缩文件后,确定已拆分的文件,并将它们重新连接在一起.这个代码并不是那么复杂(我假设splits.exe使用的命名约定,即file.001,file.002等) if(iParts>1) { //If this is a multipart binary split file,we must combine all of the parts before we can use it NSString *finalfilePath = whateveryourfinaldestinationfilenameis NSString *splitfilePath = [finalfilePath stringByAppendingString:@".001"]; NSFileHandle *myHandle; NSFileManager *fileManager = [NSFileManager defaultManager]; NSError *error; //If the target combined file exists already,remove it if ([fileManager fileExistsAtPath:finalfilePath]) { BOOL success = [fileManager removeItemAtPath:finalfilePath error:&error]; if (!success) NSLog(@"Error: %@",[error localizedDescription]); } myHandle = [NSFileHandle fileHandleForUpdatingAtPath:splitfilePath]; NSString *nextPart; //Concatenate each piece in order for (int i=2; i<=iParts; i++) { //Assumes fewer than 100 pieces if (i<10) nextPart = [splitfilePath stringByReplacingOccurrencesOfString:@".001" withString:[NSString stringWithFormat:@".00%d",i]]; else nextPart = [splitfilePath stringByReplacingOccurrencesOfString:@".001" withString:[NSString stringWithFormat:@".0%d",i]]; NSData *datapart = [[NSData alloc] initWithContentsOfFile:(NSString *)nextPart]; [myHandle seekToEndOfFile]; [myHandle writeData:datapart]; } [myHandle closeFile]; //Rename concatenated file [fileManager moveItemAtPath:splitfilePath toPath:finalfilePath error:&error]; } (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |