26

真的坚持尝试编写代码来解压缩 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);  
}
4

8 回答 8

41

我想要一个简单的解决方案,但在这里找不到我喜欢的解决方案,所以我修改了一个库来做我想做的事。您可能会发现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];
于 2010-07-21T23:20:09.947 回答
13

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

要检查,请查看文件的前两个字节。如果是“PK”,则为 WinZip,如果为 0x1F8B,则为 gZip。

因为这是 iPhone 特定的,请查看这个iPhone SDK 论坛讨论,其中提到了miniZip。看来这可以处理 WinZip 文件。

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

于 2009-01-05T12:58:23.847 回答
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.7MB 未压缩/秒。

于 2009-08-16T12:35:23.810 回答
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];
于 2011-05-20T11:35:44.750 回答
1

解压缩任意 zip 文件真的很困难。这是一种复杂的文件格式,并且可能有许多不同的压缩例程可以在文件内部使用。Info-ZIP 有一些免费许可的代码(http://www.info-zip.org/UnZip.html),可以通过一些黑客攻击在 iPhone 上工作,但坦率地说,API 很可怕——它涉及将命令行参数传递给模拟 UnZIP 运行的假“main”(公平地说,这是因为他们的代码从一开始就没有被设计成这样使用,库功能后来被固定了)。

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

于 2009-01-05T13:09:04.263 回答
1

zlib 不是用来打开 .zip 文件的,但你很幸运:zlib 的 contrib 目录包含 minizip,它能够使用 zlib 打开 .zip 文件。

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

于 2009-01-05T13:16:55.247 回答
0

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

于 2009-01-05T12:45:40.177 回答
-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 更容易......

于 2009-11-12T00:41:03.007 回答