How do I use Minizip (on Zlib)?

2020-01-29 06:40发布

问题:

I'm trying to archive files for a cross-platform application, and it looks like Minizip (built on zlib) is about as portable as archivers come.

When I try to run the following dummy code, however, I get a system error [my executable] has stopped working. Windows can check online for a solution to the problem.

Can anyone help me see how to use this library? — (there's no doc or tutorial anywhere that I can find)

zip_fileinfo zfi;

int main()
{
    zipFile zf = zipOpen("myarch.zip",APPEND_STATUS_ADDINZIP);
    int ret = zipOpenNewFileInZip(zf,
        "myfile.txt",
        &zfi,
        NULL,   0,
        NULL,   0,
        "my comment for this interior file",
        Z_DEFLATED,
        Z_NO_COMPRESSION
        );
    zipCloseFileInZip(zf);
    zipClose(zf, "my comment for exterior file");
    return 0;
}

Specs: Msys + MinGW, Windows 7, using zlibwapi.dll from zlib125dll.zip/dll32

回答1:

Since I found this question via Google and it didn't contain any complete, working code, I am providing some here for future visitors.

int CreateZipFile (std::vector<wstring> paths)
{
    zipFile zf = zipOpen(std::string(destinationPath.begin(), destinationPath.end()).c_str(), APPEND_STATUS_CREATE);
    if (zf == NULL)
        return 1;

    bool _return = true;
    for (size_t i = 0; i < paths.size(); i++)
    {
        std::fstream file(paths[i].c_str(), std::ios::binary | std::ios::in);
        if (file.is_open())
        {
            file.seekg(0, std::ios::end);
            long size = file.tellg();
            file.seekg(0, std::ios::beg);

            std::vector<char> buffer(size);
            if (size == 0 || file.read(&buffer[0], size))
            {
                zip_fileinfo zfi = { 0 };
                std::wstring fileName = paths[i].substr(paths[i].rfind('\\')+1);

                if (S_OK == zipOpenNewFileInZip(zf, std::string(fileName.begin(), fileName.end()).c_str(), &zfi, NULL, 0, NULL, 0, NULL, Z_DEFLATED, Z_DEFAULT_COMPRESSION))
                {
                    if (zipWriteInFileInZip(zf, size == 0 ? "" : &buffer[0], size))
                        _return = false;

                    if (zipCloseFileInZip(zf))
                        _return = false;

                    file.close();
                    continue;
                }
            }
            file.close();
        }
        _return = false;
    }

    if (zipClose(zf, NULL))
        return 3;

    if (!_return)
        return 4;
    return S_OK;
}


回答2:

The minizip library does come with examples; minizip.c for zipping and miniunz.c for unzipping. Both are command line utilities that show how to use the library. They are a mess though.

You also need to fill the zfi zip_fileinfo. At the very least you should initialize the structure to zero. zfi contains information about the file you want to store using zipOpenNewFileInZip. The structure should contain the date and attributes of "myfile.txt".

I recommend using PKWARE Desktop to diagnosis zip issues. It shows the structure/properties of the files in the ZIP and the ZIP file itself. When I opened the myarch.zip it told me there were errors. I drilled down into the file properties and found that the attributes were off.



回答3:

The minizip lib is well documented. Just open the zip.h for details.

I can tell you here, you may have passed a wrong parameter for zipOpen. (APPEND_STATUS_ADDINZIP requires an existing zip file!)

Also, please check whether zipOpen returns a valid zipFile handle.



标签: c zip zlib