如何解压缩包含一个文件的大型zip文件并使用swift以字节为单位获取进度?

mcf*_*oft 17 streaming unzip archive ios swift

我尝试解压缩只包含一个项目(超过100MB)的大型zip文件,并希望在解压缩过程中显示进度.

我找到了解决方案,根据解压缩的文件数量可以确定进度,但在我的情况下,我只有一个大文件.所以我猜它必须由解压缩的字节数决定?

实际上我使用SSZipArchive与以下代码工作正常:

    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);
Run Code Online (Sandbox Code Playgroud)

我找不到解决方法.

有人有样品的提示,样品或链接吗?

更新: 以下代码看起来会按预期工作,但只有一个文件被解压缩时,处理程序将只被调用一次(在解压缩结束时):

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)
                }
        })

    }
Run Code Online (Sandbox Code Playgroud)

更新2:

正如SSArchive中分析的"Martin R",它是不可能的.有没有其他方法来解压缩文件并显示基于进度的kbytes?

更新3:

在通过"roop"解释解决方案后,我更改了SSZipArchive.m,如下所示.可能其他人也可以使用它:

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;
                    }
                }
Run Code Online (Sandbox Code Playgroud)

roo*_*oop 2

为了实现你想要的,你必须修改 SSZipArchive 的内部代码。

SSZipArchive使用 minizip 提供压缩功能。您可以在此处查看 minizip 解压缩 API:unzip.h

fileInfo在 SSZipArchive.m 中,您可以从变量中获取正在解压缩的文件的未压缩大小。

您可以看到这里正在读取解压缩的内容:

 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;
     }
 }
Run Code Online (Sandbox Code Playgroud)

您将需要readBytes和未压缩文件大小来计算单个文件的进度。您可以向 SSZipArchive 添加新委托,以将这些数据发送回调用代码。