-(BOOL) UnzipFileTo:(NSString*) path overWrite:(BOOL) overwrite
{
BOOL success = YES;
int index = 0;
int progress = -1;
int ret = unzGoToFirstFile( _unzFile );
unsigned char buffer[4096] = {0};
if( ret!=UNZ_OK )
{
[self OutputErrorMessage:@"Failed"];
}
const char* password = [_password cStringUsingEncoding:NSASCIIStringEncoding];
do{
@autoreleasepool {
if( [_password length]==0 )
ret = unzOpenCurrentFile( _unzFile );
else
ret = unzOpenCurrentFilePassword( _unzFile, password );
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:self.stringEncoding]; 把這句話註釋掉換成以下兩句
NSStringEncoding enc = CFStringConvertEncodingToNSStringEncoding(kCFStringEncodingGB_18030_2000);
NSString * strPath = [NSString stringWithCString:filename encoding:enc];
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 )
[_fileManager createDirectoryAtPath:fullPath withIntermediateDirectories:YES attributes:nil error:nil];
else
[_fileManager createDirectoryAtPath:[fullPath stringByDeletingLastPathComponent] withIntermediateDirectories:YES attributes:nil error:nil];
FILE* fp = NULL;
do
{
read = unzReadCurrentFile(_unzFile, buffer, 4096);
if (read >= 0)
{
if (fp == NULL) {
if( [_fileManager fileExistsAtPath:fullPath] && !isDirectory && !overwrite )
{
if( ![self OverWrite:fullPath] )
{
// don't process any more of the file, but continue
break;
}
}
if (!isDirectory) {
fp = fopen( (const char*)[fullPath UTF8String], "wb");
if (fp == NULL) {
[self OutputErrorMessage:@"Failed to open output file for writing"];
break;
}
}
}
fwrite(buffer, read, 1, fp );
}
else // if (read < 0)
{
ret = read; // result will be an error code
success = NO;
[self OutputErrorMessage:@"Failed to read zip file"];
}
} while (read > 0);
if (fp)
{
fclose( fp );
// add the full path of this file to the output array
[(NSMutableArray*)_unzippedFiles addObject:fullPath];
// set the orignal datetime property
if( fileInfo.tmu_date.tm_year!=0 )
{
NSDateComponents* components = [[NSDateComponents alloc] init];
components.second = fileInfo.tmu_date.tm_sec;
components.minute = fileInfo.tmu_date.tm_min;
components.hour = fileInfo.tmu_date.tm_hour;
components.day = fileInfo.tmu_date.tm_mday;
components.month = fileInfo.tmu_date.tm_mon;
components.year = fileInfo.tmu_date.tm_year;
NSCalendar *gregorianCalendar = [[NSCalendar alloc] initWithCalendarIdentifier:NSGregorianCalendar];
NSDate* orgDate = [[gregorianCalendar dateFromComponents:components] retain];
[components release];
[gregorianCalendar release];
NSDictionary* attr = [NSDictionary dictionaryWithObject:orgDate forKey:NSFileModificationDate]; //[_fileManager fileAttributesAtPath:fullPath traverseLink:YES];
if( attr )
{
// [attr setValue:orgDate forKey:NSFileCreationDate];
if( ![_fileManager setAttributes:attr ofItemAtPath:fullPath error:nil] )
{
// cann't set attributes
NSLog(@"Failed to set attributes");
}
}
[orgDate release];
orgDate = nil;
}
}
if (ret == UNZ_OK) {
ret = unzCloseCurrentFile( _unzFile );
if (ret != UNZ_OK) {
[self OutputErrorMessage:@"file was unzipped but failed crc check"];
success = NO;
}
}
if (ret == UNZ_OK) {
ret = unzGoToNextFile( _unzFile );
}
if (_progressBlock && _numFiles) {
index++;
int p = index*100/_numFiles;
progress = p;
_progressBlock(progress, index, _numFiles);
}
}
} while (ret==UNZ_OK && ret!=UNZ_END_OF_LIST_OF_FILE);
return success;
}
IOS-關於第三方解壓庫ZipArchive解壓後中文亂碼問題
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.