如何解压缩包含一个文件的大型zip文件并使用swift以字节为单位获取进度? [英] How to unzip a big zip file containing one file and get the progress in bytes with swift?
问题描述
我尝试解压缩只包含一个项目(超过100MB)的大型zip文件,并希望在解压缩过程中显示进度。
I try to unzip a big zip file containing only one item (more than 100MB) and like to show the progress during unzipping.
我找到了进度的解决方案可以根据解压缩的文件数量确定,但在我的情况下,我只有一个大文件。所以我想它必须由解压缩的字节数决定?
I found solutions where the progress can be determined based on the amount of files unzipped but in my case I have only one big file inside. So I guess it must be determined by the amount of bytes unzipped?
实际上我使用SSZipArchive并使用以下代码,该代码工作正常:
Actually I am using SSZipArchive with the following code which works fine:
var myZipFile:NSString="/Users/user/Library/Developer/CoreSimulator/Devices/mydevice/ziptest/testzip.zip";
var DestPath:NSString="/Users/user/Library/Developer/CoreSimulator/Devices/mydevice/ziptest/";
let unZipped = SSZipArchive.unzipFileAtPath(myZipFile as! String, toDestination: DestPath as! String);
我找不到解决方案。
有没有人提供样品的提示,样品或链接?
Does anyone have a hint, sample or link to a sample ?
更新:
以下代码看起来像是可以的预期,但只有一个文件被解压缩时,处理程序将只被调用一次(在解压缩结束时):
UPDATE: Following code looks like it would work as intended, but the handler will be called only once (at the end of unzipping) when the only one file is unzipped:
func unzipFile(sZipFile: String, toDest: String){
SSZipArchive.unzipFileAtPath(sZipFile, toDestination: toDest, progressHandler: {
(entry, zipInfo, readByte, totalByte) -> Void in
println("readByte : \(readByte)") // <- This will be only called once, at the end of unzipping. My 500MB Zipfile holds only one file.
println("totalByte : \(totalByte)")
//Asynchrone task
dispatch_async(dispatch_get_main_queue()) {
println("readByte : \(readByte)")
println("totalByte : \(totalByte)")
//Change progress value
}
}, completionHandler: { (path, success, error) -> Void in
if success {
//SUCCESSFUL!!
} else {
println(error)
}
})
}
更新2:
正如SSArchive中分析的Martin R一样可能。
有没有其他方法来解压缩文件并显示基于进度的kbytes?
As "Martin R" analysed in SSArchive, its not possible. Is there any other way to unzip a file and show the progress based kbytes?
更新3:
在解决方案被roop解释后,我更改了SSZipArchive.m,如下所示。可能其他人也可以使用它:
I changed the SSZipArchive.m after the solution was explained by "roop" as follows. Probably someone else can use this too:
FILE *fp = fopen((const char*)[fullPath UTF8String], "wb");
while (fp) {
int readBytes = unzReadCurrentFile(zip, buffer, 4096);
if (readBytes > 0) {
fwrite(buffer, readBytes, 1, fp );
totalbytesread=totalbytesread+4096;
// Added by me
if (progressHandler)
{
progressHandler(strPath, fileInfo, currentFileNumber, totalbytesread);
}
// End added by me
} else {
break;
}
}
推荐答案
到实现你想要的,你将不得不修改SSZipArchive的内部代码。
To achieve what you want, you will have to modify SSZipArchive's internal code.
SSZipArchive 使用minizip提供压缩功能。你可以在这里看到minizip解压缩API: unzip.h 。
SSZipArchive uses minizip to provide the zipping functionality. You can see the minizip unzipping API here: unzip.h.
在SSZipArchive.m中,您可以从 fileInfo
变量。
In SSZipArchive.m, you can get the uncompressed size of the file being unzipped from the fileInfo
variable.
您可以看到正在阅读解压缩的内容这里:
You can see that the unzipped contents are being read here:
FILE *fp = fopen((const char*)[fullPath UTF8String], "wb");
while (fp) {
int readBytes = unzReadCurrentFile(zip, buffer, 4096);
if (readBytes > 0) {
fwrite(buffer, readBytes, 1, fp );
} else {
break;
}
}
您需要 readBytes
和未压缩的文件大小,用于计算单个文件的进度。您可以向SSZipArchive添加新委托,以将这些数据发送回调用代码。
You will need the readBytes
and the uncompressed file size to compute the progress for a single file. You can add a new delegate to SSZipArchive to send these data back to the calling code.
这篇关于如何解压缩包含一个文件的大型zip文件并使用swift以字节为单位获取进度?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!