如何显示文件解压进度?

2024-04-21

我正在尝试找出一种方法来显示当前进度以及解压缩并将 zip 文件的内容写入磁盘的剩余时间。我目前正在使用此处找到的 ZipArchiver 类http://code.google.com/p/ziparchive/ http://code.google.com/p/ziparchive/效果很好。问题是,其中很多都是用 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


不要“插入一些代码来显示进度”。相反,在单独的操作中执行实际工作,并将其进度传达给主线程以呈现给用户。

只需阅读您的代码,就有几个非常明显的地方可以传递此信息。例如,有一个内部循环从存档中的单个文件读取数据,还有一个外部循环迭代存档中的文件。您可以轻松创建一组委托消息,用于报告正在提取哪个文件、提取的进度以及提取在整个存档中的进度。

然后,您可以创建一个特定的委托,它知道如何与您的 UI(在主线程上)交互并向用户呈现此进度。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

如何显示文件解压进度? 的相关文章

随机推荐