使用 SSZipArchive OBJ-C 解压缩 .sqlite 文件

Unzipping .sqlite file using SSZipArchive OBJ-C

我需要从服务器下载.zip文件,解压后用于投影。我已经成功下载了 .sqlite 文件,并且可以使用右键单击(手动)将其解压缩,但是当我尝试使用 minizip 和 SSZipArchive 或 ZipArchive 将其解压缩时,出现错误 "Can't open the file"。

如果我手动提取 .sqlite 并通过右键单击 mac 压缩 .sqlite 文件,那么我的代码会完全提取它,但是每当我尝试直接提取下载的文件时,就会出现此问题。

我已经应用了以下名称格式来写入和提取文件。

  1. 写入文件时名称为 XYZ.sqlite.zip 但它也给出错误
  2. XYZ.zip,包含的文件名为 XYZ.sqlite。这也给出了错误
  3. 我也写过名称为 XYZ.sqlite.zip 的文件,然后用 XYZ.zip 重命名,然后解压缩,但这也不起作用。

下面是代码。

下载文件:

 NSURLRequest *request = [NSURLRequest requestWithURL:[NSURL URLWithString:zipURL]];
  NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
 NSString *path = [[paths objectAtIndex:0] stringByAppendingPathComponent:[zipURL lastPathComponent]];
operation = [[AFDownloadRequestOperation alloc] initWithRequest:request targetPath:path shouldResume:YES];
 [operation.securityPolicy setAllowInvalidCertificates:YES];
 [operation setCompletionBlockWithSuccess:^(AFHTTPRequestOperation *operation, id responseObject) {
 [self unzipDBFile:path];


} failure:^(AFHTTPRequestOperation *operation, NSError *error) {
    NSLog(@"Error: %@", error);
}];

[operation setProgressiveDownloadProgressBlock:
 ^(AFDownloadRequestOperation *operation, NSInteger bytesRead, long long totalBytesRead, long long totalBytesExpected, long long totalBytesReadForFile, long long totalBytesExpectedToReadForFile) {

     NSArray *progress = [NSArray arrayWithObjects:obj_Pro,[NSNumber numberWithFloat:totalBytesReadForFile/(float)totalBytesExpectedToReadForFile], nil];

     [self performSelectorOnMainThread:@selector(updateProgressBar:) withObject:progress waitUntilDone:NO];
 }];
[operation start];

解压文件:

-(void)unzipDBFile:(NSString *)filePath
{

 NSString *documentDir = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory,
                                                             NSUserDomainMask, YES) objectAtIndex:0];
   NSString *outputPath = [documentDir stringByAppendingPathComponent:@"/DBFolder"];
   BOOL isExtracted =[SSZipArchive unzipFileAtPath:outputPath toDestination:documentDir];

  // NSString *filepath = [[NSBundle mainBundle] pathForResource:@"ZipFileName" ofType:@"zip"];
 //    ZipArchive *zipArchive = [[ZipArchive alloc] init];
 //    [zipArchive UnzipOpenFile:filePath];

 //    NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
//    NSString *path = [paths objectAtIndex:0];
//    BOOL isExtracted=[zipArchive UnzipFileTo:path overWrite:YES];
//    NSLog(@"PATH=%@",path);
   if (!isExtracted)
    {
     UIAlertView *alert=[[UIAlertView alloc] initWithTitle:@"Error in extracting" message:@"" delegate:nil cancelButtonTitle:@"OK" otherButtonTitles:nil, nil];
      [alert show];
      [alert release];
   }else{
     UIAlertView *alert=[[UIAlertView alloc] initWithTitle:@"Extract Success" message:@"" delegate:nil cancelButtonTitle:@"OK" otherButtonTitles:nil, nil];
     [alert show];
     [alert release];
   }
//    [zipArchive UnzipCloseFile];
//    [zipArchive release];
}

更新进度条代码如下:

- (void)updateProgressBar:(NSArray *)progress
{
 UIProgressView *pgr = (UIProgressView *)[progress objectAtIndex:0];
 [pgr setProgress:[[progress objectAtIndex:1] floatValue]];
}

我检查了这个问题,发现创建 .zip 的 .net 开发人员使用了 gzip 压缩,因此 minizip 无法提取它。

为了解压缩它,我使用了 iOS zlib 框架和下面的代码,这已经解决了我的问题。在实施此方法之前,您必须在 header 中添加以下两件事。

#import <zlib.h>
#define CHUNK 16384

-(BOOL)unzipDBFile:(NSString *)filePath
{
NSString *documentDir = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory,
                                                             NSUserDomainMask, YES) objectAtIndex:0];
documentDir=[documentDir stringByAppendingPathComponent:DATABASE_FILE_NAME];

    gzFile file = gzopen([filePath UTF8String], "rb");
    FILE *dest = fopen([documentDir 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)) {

            return FALSE;
        }
    }
    fclose(dest);
    gzclose(file);

return TRUE;
}