win下报错,记得添加附加包含目录:
$(EngineRoot)external\win32-specific\zlib\include
#ifdef MINIZIP_FROM_SYSTEM
#include <minizip/unzip.h>
#else // from our embedded sources
#include "unzip/unzip.h"
#endif
#define BUFFER_SIZE 8192
#define MAX_FILENAME 512
bool DirLayer::uncompress(const std::string &filePath, const std::string &storagePath, bool isLocalAsset)
{
// Open the zip file
unzFile zipfile;
if (!isLocalAsset)
{
zipfile = unzOpen(FileUtils::getInstance()->getSuitableFOpen(filePath).c_str());
}
else
{
Data dataFile = FileUtils::getInstance()->getDataFromFile(filePath);
ssize_t size = 0;
unsigned char *data = dataFile.takeBuffer(&size);
zipfile = unzOpenBuffer(data, size);
}
if (!zipfile)
{
CCLOG("can not open downloaded zip file %s", filePath.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", filePath.c_str());
unzClose(zipfile);
return false;
}
// Buffer to hold data read from the zip file
char readBuffer[BUFFER_SIZE];
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[MAX_FILENAME];
if (unzGetCurrentFileInfo(zipfile,
&fileInfo,
fileName,
MAX_FILENAME,
nullptr,
0,
nullptr,
0) != UNZ_OK)
{
CCLOG("can not read file info");
unzClose(zipfile);
return false;
}
const string fullPath = storagePath + fileName;
// Check if this entry is a directory or a file.
const size_t filenameLength = strlen(fileName);
if (fileName[filenameLength - 1] == '/')
{
// Entry is a directory, so create it.
// If the directory exists, it will failed silently.
if (!FileUtils::getInstance()->createDirectory(fullPath))
{
CCLOG("can not create directory %s", fullPath.c_str());
unzClose(zipfile);
return false;
}
}
else
{
//There are not directory entry in some case.
//So we need to test whether the file directory exists when uncompressing file entry
//, if does not exist then create directory
const string fileNameStr(fileName);
size_t startIndex = 0;
size_t index = fileNameStr.find("/", startIndex);
while (index != std::string::npos)
{
const string dir = storagePath + fileNameStr.substr(0, index);
FILE *out = fopen(FileUtils::getInstance()->getSuitableFOpen(dir).c_str(), "r");
if (!out)
{
if (!FileUtils::getInstance()->createDirectory(dir))
{
CCLOG("can not create directory %s", dir.c_str());
unzClose(zipfile);
return false;
}
else
{
CCLOG("create directory %s", dir.c_str());
}
}
else
{
fclose(out);
}
startIndex = index + 1;
index = fileNameStr.find("/", startIndex);
}
// 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(FileUtils::getInstance()->getSuitableFOpen(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;
}
}
}
CCLOG("end uncompressing");
unzClose(zipfile);
return true;
}