加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

LZMA SDK使用太多RAM解压缩iOS(xcode)

发布时间:2020-12-14 17:21:54 所属栏目:百科 来源:网络整理
导读:我想在iPhone / iPad应用程序中使用LZMA SDK,我的出发点是Mo Dejong提供的LZMA iPhone示例项目,可在此处获取: https://github.com/jk/lzmaSDK 原文在这里: http://www.modejong.com/iOS/lzmaSDK.zip (我试过了两次,我从两者得到了相同的结果). 问题是提取
我想在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文件必须拆分,您可以使用任何二进制拆分器应用程序(如拆分)执行此操作:
http://www.fourmilab.ch/splits/

3)文件准备好后,使用MoDJ在他的答案中描述的字典/块大小选项创建7z文件,例如24 meg限制:
7za a -mx = 9 -md = 24m -ms = 24m CompressedFile.7z SourceFiles *

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];
    }

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读