怎么在lua中解压文件

我现在看到有个zlib,但是不懂应该怎么调用接口才能把文件解压出来
目的的为了把更新包patch.zip中的全部文件解压放到writablePath/update里面去
求大师答疑!

已经解决,贴在下面了,如果是普通的解压一段数据,用zlib轻松搞定,
解压文件到指定目录,就用我下面的代码。

zlib.deflate
zlib.inflate
有导出这两个函数,但是参数和返回值没明白怎么弄

没人帮忙,只能自己搞定了
方法是导出ZipUtils,在ZipUtils里面添加uncompressDir的方法给lua用

bool ZipUtils::uncompressDir(char* filename, char* destPath)
{
    if (filename == NULL || destPath == NULL)
    {
        CCLOG("source zip is null or dest path is null!");
        return false;
    }

    // Open the zip file
    std::string outFileName = filename;
    unzFile zipfile = unzOpen(outFileName.c_str());
    if (!zipfile)
    {
        CCLOG("can not open downloaded zip file %s", outFileName.c_str());
        return false;
    }

    // Get info about the zip file
    unz_global_info global_info;
    if (unzGetGlobalInfo(zipfile, &global_info) != UNZ_OK)
    {
        CCLOG("can not read file global info of %s", outFileName.c_str());
        unzClose(zipfile);
        return false;
    }

    const int BUFFER_SIZE = 8192;
    const int MAX_FILENAME = 512;
    // Buffer to hold data read from the zip file
    char readBuffer;

    CCLOG("start uncompressing");

    // Loop to extract all files.
    uLong i;
    for (i = 0; i < global_info.number_entry; ++i)
    {
        // Get info about current file.
        unz_file_info fileInfo;
        char fileName;
        if (unzGetCurrentFileInfo(zipfile,
            &fileInfo,
            fileName,
            MAX_FILENAME,
            NULL,
            0,
            NULL,
            0) != UNZ_OK)
        {
            CCLOG("can not read file info");
            unzClose(zipfile);
            return false;
        }

        std::string storagePath = destPath;
        std::string fullPath = storagePath + fileName;

        // Check if this entry is a directory or a file.
        const size_t filenameLength = strlen(fileName);
        if (fileName == '/')
        {
            // get all dir
            std::string fileNameStr = std::string(fileName);
            size_t position = 0;
            while ((position = fileNameStr.find_first_of("/", position)) != std::string::npos)
            {
                std::string dirPath = storagePath + fileNameStr.substr(0, position);
                // Entry is a direcotry, so create it.
                // If the directory exists, it will failed scilently.
                if (!createDirectory(dirPath.c_str()))
                {
                    CCLOG("can not create directory %s", dirPath.c_str());
                    //unzClose(zipfile);
                    //return false;
                }
                position++;
            }
        }
        else
        {
            // Entry is a file, so extract it.

            // Open current file.
            if (unzOpenCurrentFile(zipfile) != UNZ_OK)
            {
                CCLOG("can not open file %s", fileName);
                unzClose(zipfile);
                return false;
            }

            // Create a file to store current file.
            FILE *out = fopen(fullPath.c_str(), "wb");
            if (!out)
            {
                CCLOG("can not open destination file %s", fullPath.c_str());
                unzCloseCurrentFile(zipfile);
                unzClose(zipfile);
                return false;
            }

            // Write current file content to destinate file.
            int error = UNZ_OK;
            do
            {
                error = unzReadCurrentFile(zipfile, readBuffer, BUFFER_SIZE);
                if (error < 0)
                {
                    CCLOG("can not read zip file %s, error code is %d", fileName, error);
                    unzCloseCurrentFile(zipfile);
                    unzClose(zipfile);
                    return false;
                }

                if (error > 0)
                {
                    fwrite(readBuffer, error, 1, out);
                }
            } while (error > 0);

            fclose(out);
        }

        unzCloseCurrentFile(zipfile);

        // Goto next entry listed in the zip file.
        if ((i + 1) < global_info.number_entry)
        {
            if (unzGoToNextFile(zipfile) != UNZ_OK)
            {
                CCLOG("can not read next file");
                unzClose(zipfile);
                return false;
            }
        }
    }
    unzClose(zipfile);
    CCLOG("end uncompressing");

    return true;
}


```

楼主强大。。。。。。。。。。。。。。。。。。。。。。。

zlib我也看了下,不得门入,于是从楼主了。

zlib 是不直接可以用吗
local lz = require(“zlib”)
local deflated, eof = lz.deflate()(text)
local inflated = lz.inflate()(deflated)

具体的使用方法在这里:

https://github.com/brimworks/lua-zlib

— Begin quote from ____

引用第6楼yangtao19cs于2014-07-09 16:54发表的 :
zlib 是不直接可以用吗
local lz= require(“zlib”)
local deflated, eof = lz.deflate()(text)
local inflated = lz.inflate()(deflated) http://www.cocoachina.com/bbs/job.php?action=topost&tid=212537&pid=999489

— End quote

zlib这样是解压一段缓存,解压出来的东西还是缓存。
而我要解压一堆文件,释放到某个地方

请问你这类在lua中如何调用?虽然quicklib编译通过了,但是不知道如何调用这些类

local lz= require(“zlib”) 这不是调用嘛 上边有人已经回复了 不好使么?

local lz= require(“zlib”) 不能实际解压一个zip包么?

看来quick-x应该把这个方法内置了

感谢回复,zlib是可以用,但是还是找不到解压zip包的方法。我看到lua_extension/unzip中好像提供了这个类,但是实际中还是找不到例子来使用。好烦的就是quic cocos文档好少。或者是我孤陋寡闻,不知道有没有文章引荐一下?关于unzip的调用例子。

确实我在帖子里面没有写那么细致
我这里只是写了实现,但是将这个函数导出到lua的过程是没有写的
这个你可以查一下如何导出C++函数到lua
就是编辑pkg,然后导出
最后你就可以ZipUtils:uncompressDir(youZipFile)来解压了

楼主的解压还是齐全
没有自动创建目录

明白,谢谢。 :14: :14:

local txt=“aaabbbc”
local zip=require(“zlib”)
local compress=zip.deflate()
local deflated, eof, bytes_in,bytes_out =compress(txt)
输出这四个值
x?
false
7
2
求大神解释这第二个参数总是false,很无奈!!

求指导下 你第二个参数返回false是什么问题 我也一样

local deflated, eof, bytes_in, bytes_out = Zlib.deflate()(“hahahahasssss”)
print(deflated)
print(eof)
print(bytes_in)
print(bytes_out)
local inflate, eof2, bytes_in2, bytes_out2 = Zlib.inflate()(deflated)
print(inflate)
print(eof2)
print(bytes_in2)
print(bytes_out2)
输出结果:
x?
false
13
2

false
2
0

求指导啊

修改cocox源文件总归不好,后来人不好维护,单独拿出来补充了一点,可以解压xxtea加密的zip,参考了LuaLoadChunksFromZIP函数,看了代码才发现竟然秘钥是protect的。。。。。。所以我这里暂时把秘钥写死在这里了,刚出炉,还有待完善。

#include "Zip.h"

#include <string>

#include "cocos2d.h"
#include "../platform/CCPlatformDefine.h"

#include "unzip/unzip.h"
#include "external/xxtea/xxtea.h"

namespace MyUtils  {
    USING_NS_CC;
    bool Zip::uncompressZip(const char *zipFile, const char *dstPath)
    {
        const char xxteaKey] = {"xxxxxxx"};
        const char xxteaSign] = {"xxxxxx"};
        auto xxteaKeyLen = strlen(xxteaKey);
        auto xxteaSignLen = strlen(xxteaSign);
        
        if (zipFile == NULL || dstPath == NULL)
        {
            CCLOG("source zip is null or dest path is null!");
            return false;
        }
        
        auto fileUtils = FileUtils::getInstance();
        
        std::string srcFileName = fileUtils->fullPathForFilename(zipFile);
        
        if (!fileUtils->isFileExist(srcFileName)) {
            CCLOG("source zip file not exist %s",srcFileName.c_str());
            return false;
        }
        
        ssize_t size = 0;
        unsigned char *zipFileData = fileUtils->getFileData(srcFileName, "rb", &size);
        if (zipFileData == nullptr) {
            return false;
        }
        bool isXXTEA = true;
        for (int i = 0; i < xxteaKeyLen && i < size; ++i) {
            isXXTEA = zipFileData* == xxteaSign*;
        }
        
        unzFile zipfile = nullptr;
        void *buffer = nullptr;
        if (isXXTEA) { // decrypt XXTEA
            xxtea_long len = 0;
            buffer = xxtea_decrypt(zipFileData + xxteaSignLen,
                                   (xxtea_long)size - (xxtea_long)xxteaSignLen,
                                   (unsigned char*)xxteaKey,
                                   (xxtea_long)xxteaKeyLen,
                                   &len);
            free(zipFileData);
            zipFileData = nullptr;
            zipfile = unzOpenBuffer(buffer, len);
        } else {
            if (zipFileData) {
                zipfile = unzOpenBuffer(buffer, size);
            }
        }
        
        // Open the zip file
        
        if (!zipfile)
        {
            CCLOG("can not open downloaded zip file %s", srcFileName.c_str());
            return false;
        }
        
        // Get info about the zip file
        unz_global_info global_info;
        if (unzGetGlobalInfo(zipfile, &global_info) != UNZ_OK)
        {
            CCLOG("can not read file global info of %s", srcFileName.c_str());
            unzClose(zipfile);
            return false;
        }
        
        const int BUFFER_SIZE = 8192;
        const int MAX_FILENAME = 512;
        // Buffer to hold data read from the zip file
        char readBuffer;
        
        CCLOG("start uncompressing");
        
        // Loop to extract all files.
        uLong i;
        for (i = 0; i < global_info.number_entry; ++i)
        {
            // Get info about current file.
            unz_file_info fileInfo;
            char fileName;
            if (unzGetCurrentFileInfo(zipfile,
                                      &fileInfo,
                                      fileName,
                                      MAX_FILENAME,
                                      NULL,
                                      0,
                                      NULL,
                                      0) != UNZ_OK)
            {
                CCLOG("can not read file info");
                unzClose(zipfile);
                return false;
            }
            
            std::string storagePath = dstPath;
            std::string fullPath = storagePath + fileName;
            
            // Check if this entry is a directory or a file.
            const size_t filenameLength = strlen(fileName);
            if (fileName == '/')
            {
                // get all dir
                std::string fileNameStr = std::string(fileName);
                size_t position = 0;
                while ((position = fileNameStr.find_first_of("/", position)) != std::string::npos)
                {
                    std::string dirPath = storagePath + fileNameStr.substr(0, position);
                    // Entry is a direcotry, so create it.
                    // If the directory exists, it will failed scilently.
                    if (!FileUtils::getInstance()->createDirectory(dirPath.c_str()))
                    {
                        CCLOG("can not create directory %s", dirPath.c_str());
                        //unzClose(zipfile);
                        //return false;
                    }
                    position++;
                }
            }
            else
            {
                // Entry is a file, so extract it.
                
                // Open current file.
                if (unzOpenCurrentFile(zipfile) != UNZ_OK)
                {
                    CCLOG("can not open file %s", fileName);
                    unzClose(zipfile);
                    return false;
                }
                
                // Create a file to store current file.
                FILE *out = fopen(fullPath.c_str(), "wb");
                if (!out)
                {
                    CCLOG("can not open destination file %s", fullPath.c_str());
                    unzCloseCurrentFile(zipfile);
                    unzClose(zipfile);
                    return false;
                }
                
                // Write current file content to destinate file.
                int error = UNZ_OK;
                do
                {
                    error = unzReadCurrentFile(zipfile, readBuffer, BUFFER_SIZE);
                    if (error < 0)
                    {
                        CCLOG("can not read zip file %s, error code is %d", fileName, error);
                        unzCloseCurrentFile(zipfile);
                        unzClose(zipfile);
                        return false;
                    }
                    
                    if (error > 0)
                    {
                        fwrite(readBuffer, error, 1, out);
                    }
                } while (error > 0);
                
                fclose(out);
            }
            
            unzCloseCurrentFile(zipfile);
            
            // Goto next entry listed in the zip file.
            if ((i + 1) < global_info.number_entry)
            {
                if (unzGoToNextFile(zipfile) != UNZ_OK)
                {
                    CCLOG("can not read next file");
                    unzClose(zipfile);
                    return false;
                }
            }
        }
        unzClose(zipfile);
        CCLOG("end uncompressing");
        
        return true;

    }
}**