iPhone解压缩代码

时间:2009-01-05 12:34:56

标签: ios objective-c zip compression

真的坚持尝试编写代码以解压缩iPhone上的文件或目录。

下面是一些示例代码,我正在尝试解压缩一个简单的文本文件。

它解压缩文件但是它已损坏。

(void)loadView {

    NSString *DOCUMENTS_FOLDER = [NSHomeDirectory() stringByAppendingPathComponent:@"Documents"];
    NSString *path = [DOCUMENTS_FOLDER stringByAppendingPathComponent:@"sample.zip"];

    NSString *unzipeddest = [DOCUMENTS_FOLDER stringByAppendingPathComponent:@"test.txt"];  

    gzFile file = gzopen([path UTF8String], "rb");

    FILE *dest = fopen([unzipeddest UTF8String], "w");

    unsigned char buffer[CHUNK];

    int uncompressedLength = gzread(file, buffer, CHUNK);

    if(fwrite(buffer, 1, uncompressedLength, dest) != uncompressedLength ||     ferror(dest)) {
        NSLog(@"error writing data");
    }
    else{

    }

    fclose(dest);
    gzclose(file);  
}

8 个答案:

答案 0 :(得分:42)

我想要一个简单的解决方案,但没有找到我喜欢的,所以我修改了一个库来做我想要的。您可能会发现SSZipArchive很有用。 (它也可以创建zip文件。)

用法:

NSString *path = @"path_to_your_zip_file";
NSString *destination = @"path_to_the_folder_where_you_want_it_unzipped";
[SSZipArchive unzipFileAtPath:path toDestination:destination];

答案 1 :(得分:13)

“sample.zip”真的是用gZip创建的吗? .zip扩展名通常用于WinZip创建的档案。那些也可以使用zLib解压缩,但你必须解析头并使用其他例程。

要检查,请查看文件的前两个字节。如果它是'PK',它是WinZip,如果它是0x1F8B,那就是gZip。

由于这是针对iPhone的,因此请查看提及iPhone SDK forum discussionminiZip。这似乎可以处理WinZip文件。

但如果它真的是一个WinZip文件,你应该看一下WinZip specification并尝试自己解析文件。它基本上应该解析一些标题值,寻找压缩的流位置并使用zLib例程对其进行解压缩。

答案 2 :(得分:12)

这段代码对我来说非常适合gzip:

数据库的准备如下:     gzip foo.db

密钥循环遍历gzread()。上面的例子只读取第一个CHUNK字节。

#import <zlib.h>
#define CHUNK 16384


  NSLog(@"testing unzip of database");
  start = [NSDate date];
  NSString *zippedDBPath = [[[NSBundle mainBundle] resourcePath] stringByAppendingPathComponent:@"foo.db.gz"];
  NSString *unzippedDBPath = [documentsDirectory stringByAppendingPathComponent:@"foo2.db"];
  gzFile file = gzopen([zippedDBPath UTF8String], "rb");
  FILE *dest = fopen([unzippedDBPath UTF8String], "w");
  unsigned char buffer[CHUNK];
  int uncompressedLength;
  while (uncompressedLength = gzread(file, buffer, CHUNK) ) {
    // got data out of our file
    if(fwrite(buffer, 1, uncompressedLength, dest) != uncompressedLength || ferror(dest)) {
      NSLog(@"error writing data");
    }
  }
  fclose(dest);
  gzclose(file);
  NSLog(@"Finished unzipping database");

顺便说一句,我可以在77秒内将33MB解压缩到130MB,或者在未压缩/秒内解压缩约1.7 MB。

答案 3 :(得分:4)

此代码会将任何.zip文件解压缩到您的应用文档目录中,并从应用资源中获取文件。

self.fileManager = [NSFileManager defaultManager];

NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);

NSLog(@"document directory path:%@",paths);

self.documentDirectory = [paths objectAtIndex:0];

NSString *filePath = [NSString stringWithFormat:@"%@/abc", self.documentDirectory];

NSLog(@"file path is:%@",filePath);

NSString *fileContent = [[[NSBundle mainBundle] resourcePath] stringByAppendingPathComponent:@"data.zip"];


NSData *unzipData = [NSData dataWithContentsOfFile:fileContent];

[self.fileManager createFileAtPath:filePath contents:unzipData attributes:nil];

// here we go, unzipping code

ZipArchive *zipArchive = [[ZipArchive alloc] init];

if ([zipArchive UnzipOpenFile:filePath])
{
    if ([zipArchive UnzipFileTo:self.documentDirectory overWrite:NO])
    {
        NSLog(@"Archive unzip success");
        [self.fileManager removeItemAtPath:filePath error:NULL];
    }
    else
    {
        NSLog(@"Failure to unzip archive");
    }
}
else
{
    NSLog(@"Failure to open archive");
}
[zipArchive release];

答案 4 :(得分:1)

解压缩任意zip文件真的很难。它是一种复杂的文件格式,可能有许多不同的压缩例程可以在文件内部使用。 Info-ZIP有一些可以自由许可的代码(http://www.info-zip.org/UnZip.html),可以通过一些黑客攻击在iPhone上运行,但API很坦率地说它很糟糕 - 它涉及将命令行参数传递给假的'main '模拟UnZIP的运行(公平地说,因为他们的代码从来没有被设计为首先使用,所以库的功能在之后用螺栓固定)。

如果您可以控制您尝试解压缩的文件的来源,我高度建议使用其他压缩系统而不是ZIP。它具有灵活性和普遍性,非常适合在人与人之间传递文件档案,但自动化非常尴尬。

答案 5 :(得分:1)

zlib并不打算打开.zip文件,但你很幸运:zlib的contrib目录包含minizip,它可以使用zlib打开.zip文件。

它可能不会捆绑在SDK中,但您可以使用捆绑版本的zlib使用它。获取zlib源代码的副本并查看contrib / minizip。

答案 6 :(得分:0)

我没有使用iPhone,但您可能需要查看GZIP,这是一个非常便携的开源zip库,可用于许多平台。

答案 7 :(得分:-5)

我有幸在iPhone模拟器上测试了这个:

NSArray *paths = 
   NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);

NSString *documentsDirectory = [paths objectAtIndex:0];

NSString *saveLocation = 
   [documentsDirectory stringByAppendingString:@"myfile.zip"];

NSFileManager* fileManager = [NSFileManager defaultManager];

if ([fileManager fileExistsAtPath:saveLocation]) {
    [fileManager removeItemAtPath:saveLocation error:nil];

}

NSURLRequest *theRequest = 
             [NSURLRequest requestWithURL:
                [NSURL URLWithString:@"http://example.com/myfile.zip"]
             cachePolicy:NSURLRequestUseProtocolCachePolicy
             timeoutInterval:60.0];    

NSData *received = 
             [NSURLConnection sendSynchronousRequest:theRequest 
                              returningResponse:nil error:nil];    

if ([received writeToFile:saveLocation atomically:TRUE]) {      
    NSString *cmd = 
       [NSString stringWithFormat:@"unzip \"%@\" -d\"%@\"", 
       saveLocation, documentsDirectory];       

    // Here comes the magic...
    system([cmd UTF8String]);       
}

看起来比使用zlib更容易......