2012-07-06 118 views
8

我试图为跨平台应用程序存档文件,而且它看起来像Minizip(建立在zlib上)与归档程序来的一样便携。如何使用Minizip(在Zlib上)?

当我试图运行下面的虚拟代码,但是,我得到了一个系统错误[my executable] has stopped working. Windows can check online for a solution to the problem.

谁能帮我看看怎么使用这个库? —(有没有文档或教程的任何地方,我可以找到)

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

规格:MSYS + MinGW的,Windows 7中,使用zlibwapi.dll从zlib125dll.zip/dll32

回答

16

因为我通过Google发现了这个问题,它没有包含任何完整的工作代码,所以我在这里为未来的访问者提供了一些内容。

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; 
} 
+0

这很好。但有几个问题:1.这假设整个文件可以放在内存中,这看起来有些简单,但对于这个示例来说可能足够好。 2.没有任何理由说明,如果初始文件长度为0,则0长度的文件输出是错误的。3.假设这是一个错误,则不需要进行三元操作。即'if(zipWriteInFileInZip(zf,size == 0?“”:&buffer [0],size))'可以写成if(zipWriteInFileInZip(zf,&buffer [0],size))''。 4.我建议不要使用下划线前缀。我知道你在使用小写字母后,但是... *耸耸肩* – Adrian 2016-03-23 17:05:33

+0

你提出的第二和第三点是错误的。大小== 0检查是为了确保在零长度上不执行缓冲区[0]。 if语句中的逻辑或操作可以确保将零长度的文件正确地写入zip文件,并且后面的三元再次确保不会在零长度上调用buffer [0]。该代码正常工作,并按预期。 – niemiro 2016-06-10 00:35:11

+0

这被标记为C,而不是C++。 – 2017-04-14 01:55:25

2

的minizip LIB是很好记录。详情请打开zip.h。

我可以在这里告诉你,你可能传递了一个错误的参数给zipOpen。 (APPEND_STATUS_ADDINZIP需要现有的zip文件!)

此外,请检查zipOpen是否返回有效的zipFile句柄。

+0

谢谢。我将第二个参数更改为“APPEND_STATUS_CREATE”。我在zip.h中没有看到任何有效性的引用;为此,我应该检查zipfile是否为'NULL'? – JellicleCat 2012-07-07 17:32:50

+0

此外,你可以阐明什么'extrafield_local'和'extrafield_global'应该是什么?我没有找到任何示例或足够的描述。 – JellicleCat 2012-07-07 18:49:12

+0

我以前从未使用过extrafield_local和extrafield_global。对不起,我忍不住。如果您的zip.h不包含任何文档,您可以下载zlib源代码。我确信该包中的zip.h包含很好的文档。 – Rango 2012-07-08 11:56:06

3

minizip库确实带有示例; minizip.c用于压缩和miniunz.c用于解压缩。两者都是显示如何使用库的命令行实用程序。尽管他们是一团糟。您还需要填写zfi zip_fileinfo。至少你应该把结构初始化为零。 zfi包含有关您要使用zipOpenNewFileInZip存储的文件的信息。该结构应该包含“myfile.txt”的日期和属性。

我建议使用PKWARE Desktop来诊断zip问题。它显示了ZIP和ZIP文件本身中文件的结构/属性。当我打开myarch.zip时,它告诉我有错误。我深入了解文件属性,发现属性已关闭。

+1

感谢您的调查,但在上面的代码示例中,不应将'zfi'初始化为零而无需指定它?它在堆上,因为它不在任何函数之内,对吧? – JellicleCat 2012-07-09 14:09:33

+0

啊,是的,你是对的。我只是把你的代码放到一个函数中,看它是否工作。 – 2012-07-09 17:18:30

+1

你的代码应该正常工作。我没有得到任何Windows崩溃。这可能是使用DLL的问题。你有没有试过在zlib库中编译? – 2012-07-09 17:22:19