为什么minizip不归档大文件(更大的4 GB)

时间:2013-11-27 18:13:33

标签: c windows visual-studio zlib large-files

我正在尝试使用Visual Studio 2010在Windows 7 64位上使用静态minizip 库。

主要目标是归档较大的4GB文件。
我使用CMake 2.8构建zlib,并链接到我的项目 适用于较小4GB的文件,但不适用于较大的4GB文件。
为什么我使用minizip存档5GB文件有问题?
我在构建库阶段错过了什么吗? 以下是我的所有步骤,图书馆和项目: https://github.com/koponomarenko/file_compression

真的需要帮助。感谢。

已更新:

“对于较大的4GB文件无法正常工作” 表示我的测试程序在此过程中存档5GB txt文件而没有任何错误。我检查了所有5,368,709,120字节的 zipWriteInFileInZip()返回 ZIP_OK zipCloseFileInZip() zipClose()不会返回任何错误。但在创建的存档(我使用7-zip)文件信息是:

  • 未压缩的尺寸: 4,294,967,295
  • 压缩尺寸: 8,806,676
  • 属性: 空白字段
  • CRC: 81970625
  • 方法: Deflate
  • 主机操作系统: FAT
  • 版本: 45

当尝试解压缩(使用7-zip)此存档时,我收到错误消息“不支持的压缩方法”。

我还用7-zip 压缩了相同的5GB txt文件。以下是此存档中的文件信息:

  • 未压缩的尺寸: 5,368,709,120
  • 压缩尺寸: 9,608,471
  • 属性: A
  • CRC: 81970625
  • 方法: Deflate
  • 主机操作系统: FAT
  • 版本: 45

前三个字段与我的存档不同。

已更新:

void Archive::create()
{
     m_archiveHandle = zipOpen64(m_sName.c_str(), APPEND_STATUS_CREATE);

     if ( !m_archiveHandle )
     {
         throw Error("Can't create the archive. Can be already created.");
     }
}

void Archive::add(string sSrcFile, string sDstFile)
{
    //////////////////////////// create a file
    zip_fileinfo zfi;
    memset(&zfi, 0, sizeof(zfi));
    int zip64 = 1;
    int ret = zipOpenNewFileInZip64(m_archiveHandle,
        sDstFile.c_str(),
        &zfi,
        NULL, 0,
        NULL, 0,
        "my comment for this interior file",
        Z_DEFLATED,
        Z_DEFAULT_COMPRESSION,
        zip64
        );
    if ( ret != 0 )
    {
        throw Error("Can't add file to a zip archive.");
    }


    //////////////////////////// write to the file
    FILE * pFile = fopen( sSrcFile.c_str(), "rb" );
    if ( !pFile )
    {
        throw Error("Can't open target file.");
    }

    char * buf = new char[BUF_SIZE];
    int size_read = 0;
    int err;
    do
    {
        err = ZIP_OK;
        size_read = (int)fread(buf, 1, BUF_SIZE, pFile);
        if (size_read < BUF_SIZE)
            if ( feof(pFile) == 0 )
            {
                err = ZIP_ERRNO;
            }

            if (size_read > 0)
            {
                err = zipWriteInFileInZip (m_archiveHandle, buf, size_read);
            }
    } while ((err == ZIP_OK) && (size_read>0));

    delete [] buf;

    //////////////////////////// close the file
    if ( zipCloseFileInZip(m_archiveHandle) != 0 )
    {
        throw Error("Can't close added file.");
    }
}


void Archive::close()
{
    if ( !m_archiveHandle )
        return;

    if ( zipClose(m_archiveHandle, "my comment for exterior file") != 0)
    {
        throw Error( "Can't save changes and close." );
    }

    m_archiveHandle = 0;
}

我使用这个批处理文件来获取静态Zlib。我将它放在 zlib / build64 中并从“Visual Studio x64 Win64命令提示符”运行。

rem ** go to the current script directory
cd %~dp0

cmake .. -G"Visual Studio 10 Win64" -DCMAKE_INSTALL_PREFIX="C:\devel\installed\zlib64"
msbuild /P:Configuration=Debug INSTALL.vcxproj
msbuild /P:Configuration=Release INSTALL.vcxproj

更新

Total Commander和Windows资源管理器可以解压缩创建的存档。我比较了原始文件和解压缩文件的校验和(md5,sha1),它是相同的。但Total和Explorer都不显示压缩文件的属性。同时7-zip称我“不支持压缩方法”。

2013年12月9日更新:

在Windows上使用大于4GB的文件时,minizip似乎存在一些属性问题。 7-Zip和WinZip无法解压缩创建的存档。

1 个答案:

答案 0 :(得分:1)

问题在于ZIP中央目录记录的字段(额外字段和文件注释字段)的顺序。因此,如果您的文件大于4GB并且您为其添加了注释,那么您将面临此错误。

在我看来原作者停止维护这个库,但我在Github上发现了一个带有一些新变化的回购https://github.com/nmoinvaz/minizip。所以我把这个bug写给了这个回购的作者。