我正在试图找出一种方法来显示当前进度以及将zip文件的内容解压缩并写入磁盘的剩余时间。我目前正在使用此处http://code.google.com/p/ziparchive/找到的ZipArchiver类,它运行良好。问题是,很多都是用C ++编写的,我没有太多的经验。这是相关的功能:
-(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"];
}
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];
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");
}
}
}
unzCloseCurrentFile( _unzFile );
ret = unzGoToNextFile( _unzFile );
}while( ret==UNZ_OK && UNZ_OK!=UNZ_END_OF_LIST_OF_FILE );
return success;
}
我很难弄清楚如何能够插入一些代码,让我显示当前的百分比进度以及解压缩并将所有文件写入磁盘的剩余时间。关于如何实现这一目标的任何想法?
THX
答案 0 :(得分:3)
不要“插入一些代码来显示进度”。相反,在单独的操作中执行实际工作,并将其进度传递给主线程以呈现给用户。
只需阅读您的代码,就会有一些非常明显的地方可以传递这些信息。例如,有一个内部循环从归档中的单个文件读取数据,并且有一个外部循环,它遍历归档中的文件。您可以轻松创建一组委托消息,这些消息可用于报告正在提取的文件,沿着它的距离以及整个存档中提取的距离。
然后,您可以创建一个特定的委托,知道如何与您的UI(在主线程上)进行交互,并将此进展呈现给用户。
答案 1 :(得分:1)
使用:
https://github.com/mattconnolly/ZipArchive
或来自cocoapods:
pod&#39; ZipArchive&#39;,&#39; 1.1.0&#39;
只需创建一个进度块,将其分配给zip变量,然后让nslog显示。
容易......
使用:
ZipArchive *zip = [[ZipArchive alloc] init];
ZipArchiveProgressUpdateBlock progressBlock = ^ (int percentage, int filesProcessed, int numFiles) {
NSLog(@"total %d, filesProcessed %d of %d", percentage, filesProcessed, numFiles);
};
zip.progressBlock = progressBlock;
//open file
[zip UnzipOpenFile:path];
//unzip file to
[zip UnzipFileTo:contentPath overWrite:YES];
答案 2 :(得分:0)
这是您用来估计剩余时间的公式:
([TimeTaken] / [NumberOfFilesProcessed])* [NumberOfFilesRemaining] = EstTimeRemaining
TimeTaken:
自进程开始以来经过的秒数。您可以使用NSTimeInterval和NSDate函数来获得此结果。
对于百分比,您只能查看已处理文件的百分比,而不能查看当前解压缩的进度。