iPhone Unzip code

馋奶兔 提交于 2019-11-26 03:49:27

问题


Really stuck on trying to write code to unzip a file or directory on the iPhone.

Below is some sample code that I\'m using to try and unzip a simple text file.

It unzips the file but its corrupt.

(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);  
}

回答1:


Has "sample.zip" really been created with gZip? The .zip extension usually is used for archives created by WinZip. Those can also be decompressed using zLib, but you'd have to parse the header and use other routines.

To check, have a look at the first two bytes of the file. If it is 'PK', it's WinZip, if it's 0x1F8B, it's gZip.

Because this is iPhone specific, have a look at this iPhone SDK forum discussion where miniZip is mentioned. It seems this can handle WinZip files.

But if it's really a WinZip file, you should have a look at the WinZip specification and try to parse the file yourself. It basically should be parsing some header values, seeking the compressed stream position and using zLib routines to decompress it.




回答2:


I wanted an easy solution and didn't find one I liked here, so I modified a library to do what I wanted. You may find SSZipArchive useful. (It can also create zip files by the way.)

Usage:

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



回答3:


This code worked well for me for gzip:

the database was prepared like this: gzip foo.db

the key was looping over the gzread(). The example above only reads the first CHUNK bytes.

#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");

Incidentally, I can unzip 33MB into 130MB in 77 seconds or about 1.7 MB uncompressed/second.




回答4:


This code will unzip any .zip file into your app document directory and get file from app resources.

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



回答5:


It's really hard to unzip any arbitrary zip file. It's a complex file format, and there are potentially many different compression routines that could have been used internally to the file. Info-ZIP has some freely licencable code to do it (http://www.info-zip.org/UnZip.html) that can be made to work on the iPhone with some hacking, but the API is frankly horrible - it involves passing command-line arguments to a fake 'main' that simulates the running of UnZIP (to be fair that's because their code was never designed to be used like this in the first place, the library functionality was bolted on afterwards).

If you have any control of where the files you're trying to unzip are coming from, I highly recommend using another compression system instead of ZIP. It's flexibility and ubiquity make it great for passing archives of files around in person-to-person, but it's very awkward to automate.




回答6:


zlib isn't meant to open .zip files, but you are in luck: zlib's contrib directory includes minizip, which is able to use zlib to open .zip files.

It may not be bundled in the SDK, but you can probably use the bundled version of zlib use it. Grab a copy of the zlib source and look in contrib/minizip.




回答7:


I haven't used the iPhone, but you may want to look at GZIP, which is a very portable open source zip library available for many platforms.




回答8:


I had some luck testing this on the iPhone simulator:

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

It looks easier than fiddling about with zlib...



来源:https://stackoverflow.com/questions/412982/iphone-unzip-code

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!