Introduction
This is a simple class for compressing and extracting files. It works depend on minizip, which is a open source zip format library. And it’s included in the attachment.
The major class name is ZipArchive, it’s easy to use, you can declare a instance and call initialize functions, and then call addFileToZip or UnzipFileTo to finish compression or uncompression.
Details
Usage: Add all the files to you project, and and framework libz.1.2.3.dylib.
include ZipArchive.h using #import "ZipArchive/ZipArchive.h"
To create and add files to a zip
BOOL ret = [zip CreateZipFile2:l_zipfile];
// OR
BOOL ret = [zip CreateZipFile2:l_zipfile Password:@"your password"]; //
//if the Password is empty, will get the same effect as [zip CreateZipFile2:l_zipfile];
ret = [zip addFileToZip:l_photo newname:@"photo.jpg"];
if( ![zip CloseZipFile2] )
{
// error handler here
}
[zip release];
Extract files in a zip file to special directory, if the directory does not exist, the class will create it automatically. also if you pass ‘overWrite’ as ‘YES’ it will overwrite files already exist. You can also implement the methods of ZipArchiveDelegate to give more choices for overwriting.
ZipArchive* za = [[ZipArchive alloc] init];
if( [za UnzipOpenFile:@"/Volumes/data/testfolder/Archive.zip"] )
// OR
if( [za UnzipOpenFile:@"/Volumes/data/testfolder/Archive.zip"] Password:@"password of the zip file"] )
// if the Password is empty, get same effect as if( [za UnzipOpenFile:@"/Volumes/data/testfolder/Archive.zip"] )
{
BOOL ret = [za UnzipFileTo:@"/Volumes/data/testfolder/extract" overWrite:YES];
if( NO==ret )
{
// error handler here
}
[za UnzipCloseFile];
}
[za release];
Unfortunately, the sample code here isn't even close to correct syntax. Should be
unzip should be
ZipArchive *za = [[ZipArchive alloc] init]; if ([za UnzipOpenFile: @"/Volumes/data/testfolder/Archive.zip"]) { BOOL ret = [za UnzipFileTo: @"/Volumes/data/testfolde/extract" overWrite: YES]; if (NO == ret){} [za UnzipCloseFile]; } [za release];Thanks John teaching me to correct the code format
Dear Everyone
If you wish to add a function to merely list the items in the zip file, and return this as an NSString array, insert the following lines into ZipArchive?.mm:
- (NSMutableArray *) getZipFileContents { BOOL success = YES; int ret = unzGoToFirstFile( _unzFile ); NSMutableArray * AllFilenames = [[NSMutableArray alloc] initWithCapacity:40]; if( ret!=UNZ_OK ) { [self OutputErrorMessage:@"Failed"]; } do{ if( [_password length]==0 ) ret = unzOpenCurrentFile( _unzFile ); else ret = unzOpenCurrentFilePassword( _unzFile, [_password cStringUsingEncoding:NSASCIIStringEncoding] ); if( ret!=UNZ_OK ) { [self OutputErrorMessage:@"Error occured"]; success = NO; break; } // reading data and write to file unz_file_info fileInfo ={0}; ret = unzGetCurrentFileInfo(_unzFile, &fileInfo, NULL, 0, NULL, 0, NULL, 0); if( ret!=UNZ_OK ) { [self OutputErrorMessage:@"Error occurs while getting file info"]; success = NO; unzCloseCurrentFile( _unzFile ); break; } char* filename = (char*) malloc( fileInfo.size_filename +1 ); unzGetCurrentFileInfo(_unzFile, &fileInfo, filename, fileInfo.size_filename + 1, NULL, 0, NULL, 0); filename[fileInfo.size_filename] = '\0'; // check if it contains directory NSString * strPath = [NSString stringWithCString:filename]; BOOL isDirectory = NO; if( filename[fileInfo.size_filename-1]=='/' || filename[fileInfo.size_filename-1]=='\\') isDirectory = YES; free( filename ); if( [strPath rangeOfCharacterFromSet:[NSCharacterSet characterSetWithCharactersInString:@"/\\"]].location!=NSNotFound ) {// contains a path strPath = [strPath stringByReplacingOccurrencesOfString:@"\\" withString:@"/"]; } // Copy name to array [AllFilenames addObject:[strPath copy]]; unzCloseCurrentFile( _unzFile ); ret = unzGoToNextFile( _unzFile ); } while( ret==UNZ_OK && UNZ_OK!=UNZ_END_OF_LIST_OF_FILE ); return [AllFilenames autorelease]; }...and of course, in ZipArchive?.h:
Thanks for sharing your work. It works fine for me....
If it uses minizip, why does it need the libz.1.2.3.dylib framework?
Thanks for nice lib!
This lib will be complete if it support specifying text encoding explicitly for filenames. (or UTF8 at least)
Thank you very much for this great library :)
how do I make it work for zip file that has been renamed to an arbitrary extension , i.e .xyz?
where in the lib that detects for .zip in filename/filepath?
Thank you for your help.
Could you please contact me, I would like to help you polish up the project a bit. There are a couple of things to change to make it not cause warnings in Xcode's build&analyze. Also I have written a method to add NSData directly to a ZIP without going via a temporary file.
oliver@drobnik.com oliver.drobnik@gmail.com
Unless I'm mistaken, it looks like I can only add files, correct? (that is, there is no support for adding a directory). Am I missing something?
Thanks!
Yeah, I'm rather confused as to why you cant add directories to the zip file?
You can add directory structure by slapping it in the second argument of addFileToZip:newname: like: [zipArchive addFileToZip:localFilePath newname:@"some_directory/my_pic.jpg"];
Hi,
How I can know whether a given zip file is encrypted or not? So I can decide to use the right UnzipOpenFile?
Hi, can anyone tell me if/how its possible to add a progress bar to display the current unzip progress and how long it will take to unzip the entire zip file/
thx
nice library...but when i used the method getzipfilecontents and stored results in nsmutable array ...nothing shows and the app hangs???how to use that function?
Hi , fist of all , thanks for this great piece of code. I am currently using it with Xcode 3.2 and SL 10.6. I get a warning for this deprecated function:
To remove that warning, i just changed that function call to this one:
best regards.
Just in case someone is interested, i added a new function to unzip the files in memory (NSData), instead of unzipping to files.
I use this library to handle a lot of small files, and it seemed that writing to temporary files was a bit of overhead. This function returns an array of dictionaries which include the file name and data for each file in the zip (directories are ignored)
regards
-(NSArray*) UnzipFileToData { NSMutableArray *array = [NSMutableArray arrayWithCapacity:5]; BOOL success = YES; int ret = unzGoToFirstFile( _unzFile ); unsigned char buffer[4096] = {0}; if( ret!=UNZ_OK ) { [self OutputErrorMessage:@"Failed"]; return nil; } do{ if( [_password length]==0 ) ret = unzOpenCurrentFile( _unzFile ); else ret = unzOpenCurrentFilePassword( _unzFile, [_password cStringUsingEncoding:NSASCIIStringEncoding] ); if( ret!=UNZ_OK ) { [self OutputErrorMessage:@"Error occurs"]; success = NO; break; } // reading data and write to file int read ; unz_file_info fileInfo ={0}; ret = unzGetCurrentFileInfo(_unzFile, &fileInfo, NULL, 0, NULL, 0, NULL, 0); if( ret!=UNZ_OK ) { [self OutputErrorMessage:@"Error occurs while getting file info"]; success = NO; unzCloseCurrentFile( _unzFile ); break; } char* filename = (char*) malloc( fileInfo.size_filename +1 ); unzGetCurrentFileInfo(_unzFile, &fileInfo, filename, fileInfo.size_filename + 1, NULL, 0, NULL, 0); filename[fileInfo.size_filename] = '\0'; // check if it contains directory NSString * strPath = [NSString stringWithCString:filename encoding:NSUTF8StringEncoding]; BOOL isDirectory = NO; if( filename[fileInfo.size_filename-1]=='/' || filename[fileInfo.size_filename-1]=='\\') isDirectory = YES; free( filename ); if( isDirectory ) { // Nothig to do with directories unzCloseCurrentFile( _unzFile ); ret = unzGoToNextFile( _unzFile ); continue; } NSMutableData *data = [[NSMutableData alloc] init]; while( 1 ) { read=unzReadCurrentFile(_unzFile, buffer, 4096); if( read > 0 ) { [data appendBytes:buffer length:read]; } else if( read<0 ) { [self OutputErrorMessage:@"Failed to read zip file"]; break; } else break; } NSDictionary *dict = [NSDictionary dictionaryWithObjectsAndKeys:data,@"data", strPath, @"filename",nil]; [array addObject:dict]; unzCloseCurrentFile( _unzFile ); ret = unzGoToNextFile( _unzFile ); }while( ret==UNZ_OK && UNZ_OK!=UNZ_END_OF_LIST_OF_FILE ); return success==NO?nil:[NSArray arrayWithArray:array]; }@ s.newave: Ofc it is able to add a progressbar for download. But if you wanna add one for unzip, you may do it in another thread as the main thread. Also you have to rework the code a little bit. I am downloading files bigger than 200MB (the largest was 380MB) and unzip them. Unzipping takes a few seconds at all. So a progressbar is not really helpfull for me.
@carlos, @ ecar
Why didn't you comtribute your code into ZipArchive?.
@carlos, BTW, Maybe the UTF8 encoded filename is a point(Such as Chinese file name).
@ acsolu
I downloaded the ZipArchive? soucefiles and import it into my project. Every thing go well, but Chinese files' name can't be display correctly while unziping zip file into specified SL directory.
Fortunately, I fixed it in your source code just now and share it: That is, In line 210 of file ZipArchive?.mm, replace the original code "NSString strPath = stringWithCString:filename?;" with "NSString strPath = stringWithUTF8String:filename?;".
Acutaully, XCode will promp warning with original code. By the way, My SL is 4.2.1, XCode is 3.2.5
Because I am Chinese guy, so I only test it in En and Chinese situation. So please check it.
This is one epic library <3 I am able to unzip a file. Only issue I have now, is zipping files. If u look at the first post it says
quote?BOOL ret = CreateZipFile2:l_zipfile?;
Can't figure it out. Any idea?
awesome library, helped me a lot :) ... thanks
Ondrej
http://www.xprogress.com | iPhone dev tutorials
thank you for your sharing
Hi, thank you for sharing this great work.
I'm dealing with an unziping problem. In fact, the function unzlocal_SearchCentralDir?(in unzip.c) is always return 0, so i can't open the zip file. Does somebody have already faced the same issues ?
Thank you for your help. (if it's not the right place to ask the question, feel free to redirect me :) ).
Hi, thank you!
and I add progress methods to ZipArchive?.
// // ZipArchive.h // // // Created by aish on 08-9-11. // acsolu@gmail.com // Copyright 2008 Inc. All rights reserved. // // History: // 09-11-2008 version 1.0 release // 10-18-2009 version 1.1 support password protected zip files // 10-21-2009 version 1.2 fix date bug #import <UIKit/UIKit.h> #include "minizip/zip.h" #include "minizip/unzip.h" @protocol ZipArchiveDelegate <NSObject> @optional -(void) ErrorMessage:(NSString*) msg; -(BOOL) OverWriteOperation:(NSString*) file; -(void) UnzipProgress:(uLong)myCurrentFileIndex total:(uLong)myTotalFileCount; @end @interface ZipArchive : NSObject { @private zipFile _zipFile; unzFile _unzFile; NSString* _password; uLong _totalFileCount; id<ZipArchiveDelegate> _delegate; } @property (nonatomic, assign) id<ZipArchiveDelegate> delegate; -(BOOL) CreateZipFile2:(NSString*) zipFile; -(BOOL) CreateZipFile2:(NSString*) zipFile Password:(NSString*) password; -(BOOL) addFileToZip:(NSString*) file newname:(NSString*) newname; -(BOOL) CloseZipFile2; -(BOOL) UnzipOpenFile:(NSString*) zipFile; -(BOOL) UnzipOpenFile:(NSString*) zipFile Password:(NSString*) password; -(BOOL) UnzipFileTo:(NSString*) path overWrite:(BOOL) overwrite; -(NSMutableArray *) getZipFileContents; -(BOOL) UnzipCloseFile; @end // // ZipArchive.mm // // // Created by aish on 08-9-11. // acsolu@gmail.com // Copyright 2008 Inc. All rights reserved. // #import "ZipArchive.h" #import "zlib.h" #import "zconf.h" @interface ZipArchive (Private) -(void) OutputErrorMessage:(NSString*) msg; -(BOOL) OverWrite:(NSString*) file; -(void) DoUnzipProgress:(uLong)myCurrentFileIndex; -(NSDate*) Date1980; @end @implementation ZipArchive @synthesize delegate = _delegate; -(id) init { if( (self=[super init])) { _zipFile = NULL ; _totalFileCount = 0; } return self; } -(void) dealloc { [self CloseZipFile2]; [super dealloc]; } -(BOOL) CreateZipFile2:(NSString*) zipFile { _zipFile = zipOpen( (const char*)[zipFile UTF8String], 0 ); if( !_zipFile ) return NO; return YES; } -(BOOL) CreateZipFile2:(NSString*) zipFile Password:(NSString*) password { _password = password; return [self CreateZipFile2:zipFile]; } -(BOOL) addFileToZip:(NSString*) file newname:(NSString*) newname; { if( !_zipFile ) return NO; // tm_zip filetime; time_t current; time( ¤t ); zip_fileinfo zipInfo = {0}; // zipInfo.dosDate = (unsigned long) current; NSDictionary* attr = [[NSFileManager defaultManager] attributesOfItemAtPath:file error:nil];//[[NSFileManager defaultManager] fileAttributesAtPath:file traverseLink:YES]; if( attr ) { NSDate* fileDate = (NSDate*)[attr objectForKey:NSFileModificationDate]; if( fileDate ) { // some application does use dosDate, but tmz_date instead // zipInfo.dosDate = [fileDate timeIntervalSinceDate:[self Date1980] ]; NSCalendar* currCalendar = [NSCalendar currentCalendar]; uint flags = NSYearCalendarUnit | NSMonthCalendarUnit | NSDayCalendarUnit | NSHourCalendarUnit | NSMinuteCalendarUnit | NSSecondCalendarUnit ; NSDateComponents* dc = [currCalendar components:flags fromDate:fileDate]; zipInfo.tmz_date.tm_sec = [dc second]; zipInfo.tmz_date.tm_min = [dc minute]; zipInfo.tmz_date.tm_hour = [dc hour]; zipInfo.tmz_date.tm_mday = [dc day]; zipInfo.tmz_date.tm_mon = [dc month] - 1; zipInfo.tmz_date.tm_year = [dc year]; } } int ret ; NSData* data = nil; if( [_password length] == 0 ) { ret = zipOpenNewFileInZip( _zipFile, (const char*) [newname UTF8String], &zipInfo, NULL,0, NULL,0, NULL,//comment Z_DEFLATED, Z_DEFAULT_COMPRESSION ); } else { data = [ NSData dataWithContentsOfFile:file]; uLong crcValue = crc32( 0L,NULL, 0L ); crcValue = crc32( crcValue, (const Bytef*)[data bytes], [data length] ); ret = zipOpenNewFileInZip3( _zipFile, (const char*) [newname UTF8String], &zipInfo, NULL,0, NULL,0, NULL,//comment Z_DEFLATED, Z_DEFAULT_COMPRESSION, 0, 15, 8, Z_DEFAULT_STRATEGY, [_password cStringUsingEncoding:NSASCIIStringEncoding], crcValue ); } if( ret!=Z_OK ) { return NO; } if( data==nil ) { data = [ NSData dataWithContentsOfFile:file]; } unsigned int dataLen = [data length]; ret = zipWriteInFileInZip( _zipFile, (const void*)[data bytes], dataLen); if( ret!=Z_OK ) { return NO; } ret = zipCloseFileInZip( _zipFile ); if( ret!=Z_OK ) return NO; return YES; } -(BOOL) CloseZipFile2 { _totalFileCount = 0; _password = nil; if( _zipFile==NULL ) return NO; BOOL ret = zipClose( _zipFile,NULL )==Z_OK?YES:NO; _zipFile = NULL; return ret; } -(BOOL) UnzipOpenFile:(NSString*) zipFile { _unzFile = unzOpen( (const char*)[zipFile UTF8String] ); if( _unzFile ) { unz_global_info globalInfo = {0}; if( unzGetGlobalInfo(_unzFile, &globalInfo )==UNZ_OK ) { NSLog(@"%lu entries in the zip file", globalInfo.number_entry); _totalFileCount = globalInfo.number_entry; } } return _unzFile!=NULL; } -(BOOL) UnzipOpenFile:(NSString*) zipFile Password:(NSString*) password { _password = password; return [self UnzipOpenFile:zipFile]; } -(BOOL) UnzipFileTo:(NSString*) path overWrite:(BOOL) overwrite { BOOL success = YES; int ret = unzGoToFirstFile( _unzFile ); unsigned char buffer[4096] = {0}; NSFileManager* fman = [NSFileManager defaultManager]; if( ret!=UNZ_OK ) { [self OutputErrorMessage:@"Failed"]; } uLong kFileCount = 0; do{ if( [_password length]==0 ) ret = unzOpenCurrentFile( _unzFile ); else ret = unzOpenCurrentFilePassword( _unzFile, [_password cStringUsingEncoding:NSASCIIStringEncoding] ); if( ret!=UNZ_OK ) { [self OutputErrorMessage:@"Error occurs"]; success = NO; break; } // reading data and write to file int read ; unz_file_info fileInfo ={0}; ret = unzGetCurrentFileInfo(_unzFile, &fileInfo, NULL, 0, NULL, 0, NULL, 0); if( ret!=UNZ_OK ) { [self OutputErrorMessage:@"Error occurs while getting file info"]; success = NO; unzCloseCurrentFile( _unzFile ); break; } char* filename = (char*) malloc( fileInfo.size_filename +1 ); unzGetCurrentFileInfo(_unzFile, &fileInfo, filename, fileInfo.size_filename + 1, NULL, 0, NULL, 0); filename[fileInfo.size_filename] = '\0'; // check if it contains directory NSString * strPath = [NSString stringWithFormat:@"%s", filename];//[NSString stringWithCString:filename]; BOOL isDirectory = NO; if( filename[fileInfo.size_filename-1]=='/' || filename[fileInfo.size_filename-1]=='\\') isDirectory = YES; free( filename ); if( [strPath rangeOfCharacterFromSet:[NSCharacterSet characterSetWithCharactersInString:@"/\\"]].location!=NSNotFound ) {// contains a path strPath = [strPath stringByReplacingOccurrencesOfString:@"\\" withString:@"/"]; } NSString* fullPath = [path stringByAppendingPathComponent:strPath]; if( isDirectory ) [fman createDirectoryAtPath:fullPath withIntermediateDirectories:YES attributes:nil error:nil]; else [fman createDirectoryAtPath:[fullPath stringByDeletingLastPathComponent] withIntermediateDirectories:YES attributes:nil error:nil]; if( [fman fileExistsAtPath:fullPath] && !isDirectory && !overwrite ) { if( ![self OverWrite:fullPath] ) { unzCloseCurrentFile( _unzFile ); ret = unzGoToNextFile( _unzFile ); continue; } } FILE* fp = fopen( (const char*)[fullPath UTF8String], "wb"); while( fp ) { read=unzReadCurrentFile(_unzFile, buffer, 4096); if( read > 0 ) { fwrite(buffer, read, 1, fp ); } else if( read<0 ) { [self OutputErrorMessage:@"Failed to reading zip file"]; break; } else break; } if( fp ) { fclose( fp ); // set the orignal datetime property NSDate* orgDate = nil; //{{ thanks to brad.eaton for the solution NSDateComponents *dc = [[NSDateComponents alloc] init]; dc.second = fileInfo.tmu_date.tm_sec; dc.minute = fileInfo.tmu_date.tm_min; dc.hour = fileInfo.tmu_date.tm_hour; dc.day = fileInfo.tmu_date.tm_mday; dc.month = fileInfo.tmu_date.tm_mon+1; dc.year = fileInfo.tmu_date.tm_year; NSCalendar *gregorian = [[NSCalendar alloc] initWithCalendarIdentifier:NSGregorianCalendar]; orgDate = [gregorian dateFromComponents:dc] ; [dc release]; [gregorian release]; //}} NSDictionary* attr = [NSDictionary dictionaryWithObject:orgDate forKey:NSFileModificationDate]; //[[NSFileManager defaultManager] fileAttributesAtPath:fullPath traverseLink:YES]; if( attr ) { // [attr setValue:orgDate forKey:NSFileCreationDate]; if( ![[NSFileManager defaultManager] setAttributes:attr ofItemAtPath:fullPath error:nil] ) { // cann't set attributes NSLog(@"Failed to set attributes"); } } kFileCount++; [self DoUnzipProgress:kFileCount]; } unzCloseCurrentFile( _unzFile ); ret = unzGoToNextFile( _unzFile ); }while( ret==UNZ_OK && UNZ_OK!=UNZ_END_OF_LIST_OF_FILE ); return success; } -(NSMutableArray *) getZipFileContents { BOOL success = YES; int ret = unzGoToFirstFile( _unzFile ); NSMutableArray * AllFilenames = [[NSMutableArray alloc] initWithCapacity:40]; if( ret!=UNZ_OK ) { [self OutputErrorMessage:@"Failed"]; } do{ if( [_password length]==0 ) ret = unzOpenCurrentFile( _unzFile ); else ret = unzOpenCurrentFilePassword( _unzFile, [_password cStringUsingEncoding:NSASCIIStringEncoding] ); if( ret!=UNZ_OK ) { [self OutputErrorMessage:@"Error occured"]; success = NO; break; } // reading data and write to file unz_file_info fileInfo ={0}; ret = unzGetCurrentFileInfo(_unzFile, &fileInfo, NULL, 0, NULL, 0, NULL, 0); if( ret!=UNZ_OK ) { [self OutputErrorMessage:@"Error occurs while getting file info"]; success = NO; unzCloseCurrentFile( _unzFile ); break; } char* filename = (char*) malloc( fileInfo.size_filename +1 ); unzGetCurrentFileInfo(_unzFile, &fileInfo, filename, fileInfo.size_filename + 1, NULL, 0, NULL, 0); filename[fileInfo.size_filename] = '\0'; // check if it contains directory NSString * strPath = [NSString stringWithFormat:@"%s", filename];//[NSString stringWithCString:filename]; BOOL isDirectory = NO; if( filename[fileInfo.size_filename-1]=='/' || filename[fileInfo.size_filename-1]=='\\') isDirectory = YES; free( filename ); if( [strPath rangeOfCharacterFromSet:[NSCharacterSet characterSetWithCharactersInString:@"/\\"]].location!=NSNotFound ) {// contains a path strPath = [strPath stringByReplacingOccurrencesOfString:@"\\" withString:@"/"]; } // Copy name to array [AllFilenames addObject:[strPath copy]]; unzCloseCurrentFile( _unzFile ); ret = unzGoToNextFile( _unzFile ); } while( ret==UNZ_OK && UNZ_OK!=UNZ_END_OF_LIST_OF_FILE ); return [AllFilenames autorelease]; } -(BOOL) UnzipCloseFile { _totalFileCount = 0; _password = nil; if( _unzFile ) return unzClose( _unzFile )==UNZ_OK; return YES; } #pragma mark wrapper for delegate -(void) OutputErrorMessage:(NSString*) msg { if( _delegate && [_delegate respondsToSelector:@selector(ErrorMessage)] ) [_delegate ErrorMessage:msg]; } -(BOOL) OverWrite:(NSString*) file { if( _delegate && [_delegate respondsToSelector:@selector(OverWriteOperation)] ) return [_delegate OverWriteOperation:file]; return YES; } -(void) DoUnzipProgress:(uLong)myCurrentFileIndex { if( _delegate && [_delegate respondsToSelector:@selector(UnzipProgress:total:)] ) [_delegate UnzipProgress:myCurrentFileIndex total:_totalFileCount]; } #pragma mark get NSDate object for 1980-01-01 -(NSDate*) Date1980 { NSDateComponents *comps = [[NSDateComponents alloc] init]; [comps setDay:1]; [comps setMonth:1]; [comps setYear:1980]; NSCalendar *gregorian = [[NSCalendar alloc] initWithCalendarIdentifier:NSGregorianCalendar]; NSDate *date = [gregorian dateFromComponents:comps]; [comps release]; [gregorian release]; return date; } @endI've changed a bit header and few lines in implementation for ARC compatibility:
In header I've removed "private parts" and minizip dependency:
and in implementation I've removed (Private) category and added private parts and minizip dependency:
// // ZipArchive.mm // // // Created by aish on 08-9-11. // acsolu@gmail.com // Copyright 2008 Inc. All rights reserved. // #import "ZipArchive.h" #import "zlib.h" #import "zconf.h" #include "minizip/zip.h" #include "minizip/unzip.h" @interface ZipArchive() { @private zipFile _zipFile; unzFile _unzFile; NSString* _password; unsigned long _totalFileCount; id<ZipArchiveDelegate> _delegate; } -(void) OutputErrorMessage:(NSString*) msg; -(BOOL) OverWrite:(NSString*) file; -(void) DoUnzipProgress:(unsigned long)myCurrentFileIndex; -(NSDate*) Date1980; @end @implementation ZipArchive // ... rest is the sameYou still have to turn off ARC for the ZipArchive?.mm, but things that don't belong to header (at least we don't need to know about) are moved to the implementation.
Is it my problem or it doesn't unzip empty folders!?
I have a zip file that contains an empty folder inside a folder, like this:
file.zip
When unzip the file i get only the folders that has some file different than folders, I don't get "emptyFolder" neither "someFolder".
Can someone tell whats wrong!? Or point me any solution??
Thanks
Here are a couple methods for deep copying a directory to a zip:
- (BOOL)addDirectoryToZip:(NSString*)fromPath toPathInZip:(NSString *)toPathInZip { // deep copy contents of fromPath directory to toPathInZip NSFileManager *fileManager = [NSFileManager defaultManager]; BOOL isDir; if (fromPath == nil || ![fileManager fileExistsAtPath:fromPath isDirectory:&isDir] || !isDir) { return NO; } toPathInZip = toPathInZip != nil ? toPathInZip : @""; NSDirectoryEnumerator *dirEnum = [fileManager enumeratorAtPath:fromPath]; if (dirEnum == NULL) { return NO; } BOOL okay = YES; while (NSString *nextFile = [dirEnum nextObject]) { NSString *nextFromPath = [fromPath stringByAppendingPathComponent:nextFile]; NSString *nextToPathInZip = [toPathInZip stringByAppendingPathComponent:nextFile]; (void)[fileManager fileExistsAtPath:nextFromPath isDirectory:&isDir]; if (!isDir) { okay = [self addFileToZip:nextFromPath newname:nextToPathInZip]; if (!okay) { break; } } } return okay; } - (BOOL)addDirectoryToZip:(NSString*)fromPath { // deep copy directory contents to top level of zip return [self addDirectoryToZip:fromPath toPathInZip:@""]; }Can we move this project to github already? :P
Hi, I get 4 warnings as follows:
1: in mztools.c
extern int ZEXPORT unzRepair(file, fileOut, fileOutTmp, nRecovered, bytesRecovered) "no previous prototype for function unzRepair"
2: in unzip.c
int err=UNZ_OK; "unused variable err"
3: in ziparchive.mm
NSDictionary attr = [defaultManager? fileAttributesAtPath:file traverseLink:YES]; " fileAttributesAtPath:traverseLink deprecated"
4. in ziparchive.mm
NSString strPath = stringWithCString:filename?; "stringWithCString deprecated"
Thanks
I seem to be experiencing problems when providing a password for the zip file:
if (!CreateZipFile2:zipFilePath Password:zipPassword?) {
}this creates a zip file and if I provide no password (zipPassword = nil) I can drag the created zip file to my desktop and unzip and see content correctly.
However if zipPassword contains a password the zip file is again created and I can again drag to my desktop but when I try to uncompress I get the error:
"unable to unarchive "test.zip" to desktop - Error 1 operation not permitted"
I was expecting to be prompted to enter the password?
Pyong's progress reporting only works when there are no directories in the ZIP file. The following change to Pyong's code will report progress correctly when directory structures are present:
if( isDirectory ) { [fman createDirectoryAtPath:fullPath withIntermediateDirectories:YES attributes:nil error:nil]; [self DoUnzipProgress:kFileCount++]; }