如何解压缩包含一个文件的大 zip 文件并快速获取以字节为单位的进度? [英] 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:
正如Martin R"在 SSArchive 中分析的那样,这是不可能的.有没有其他方法可以解压缩文件并显示基于进度的千字节?
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 文件并快速获取以字节为单位的进度?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!