将下面两方法加入AssetsManagerEx类,用法:直接调用AssetsManagerEx对象->decodPlazaRes("文件名.zip");
//解压文件
bool AssetsManagerEx::decompressPlaza(const std::string &zip)
{
// Find root path for zip file
size_t pos = zip.find_last_of("/\\");
if (pos == std::string::npos)
{
CCLOG("AssetsManagerEx : no root path specified for zip file %s\n", zip.c_str());
return false;
}
//解压后资源路径
const std::string rootPath = FileUtils::getInstance()->getWritablePath()+"PlazaResources/";
// Open the zip file
unzFile zipfile = unzOpen(FileUtils::getInstance()->getSuitableFOpen(zip).c_str());
if (! zipfile)
{
CCLOG("AssetsManagerEx : can not open downloaded zip file %s\n", zip.c_str());
return false;
}
// Get info about the zip file
unz_global_info global_info;
if (unzGetGlobalInfo(zipfile, &global_info) != UNZ_OK)
{
CCLOG("AssetsManagerEx : can not read file global info of %s\n", zip.c_str());
unzClose(zipfile);
return false;
}
// Buffer to hold data read from the zip file
char readBuffer[BUFFER_SIZE];
// 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,
NULL,
0,
NULL,
0) != UNZ_OK)
{
CCLOG("AssetsManagerEx : can not read compressed file info\n");
unzClose(zipfile);
return false;
}
std::string fullPath = rootPath+fileName;
// Check if this entry is a directory or a file.
const size_t filenameLength = strlen(fileName);
if (fileName[filenameLength-1] == '/')
{
//There are not directory entry in some case.
//So we need to create directory when decompressing file entry
if ( !_fileUtils->createDirectory(basename(fullPath)) )
{
// Failed to create directory
CCLOG("AssetsManagerEx : can not create directory %s\n", fullPath.c_str());
unzClose(zipfile);
return false;
}
}
else
{
// Entry is a file, so extract it.
// Open current file.
if (unzOpenCurrentFile(zipfile) != UNZ_OK)
{
CCLOG("AssetsManagerEx : can not extract file %s\n", 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("AssetsManagerEx : can not create decompress destination file %s\n", 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("AssetsManagerEx : can not read zip file %s, error code is %d\n", fileName, error);
fclose(out);
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("AssetsManagerEx : can not read next file for decompressing\n");
unzClose(zipfile);
return false;
}
}
}
unzClose(zipfile);
return true;
}
//fileName .zip文件名
void AssetsManagerEx::decodPlazaRes(std::string fileName)
{
auto fileUtils = FileUtils::getInstance();
std::string path = fileUtils->fullPathForFilename(fileName);
if(path == "") return;
//将安装包资源文件拷贝至沙盒路径下
std::string dataFilePath = FileUtils::getInstance()->getWritablePath() +"PlazaResources/" + fileName;
int pos = path.find("PlazaResources");
if(pos == string::npos)
{
std::string strPath = FileUtils::getInstance()->fullPathForFilename(fileName);
ssize_t len = 0;
unsigned char *data = 0;
CCLOG("strPath:%s",strPath.c_str());
data = FileUtils::getInstance()->getFileData(strPath.c_str(), "r", &len);
CCLOG("file:%s, len:%zd", dataFilePath.c_str(), len);
FILE* fp = fopen(dataFilePath.c_str(), "wb");
if(!fp)
{
CCLOG("file not found!");
}
fwrite(data, sizeof(char), len, fp);
fclose(fp);
delete []data;
data = 0;
fileUtils->removeFile(path);
}
//执行解压
struct AsyncData
{
std::vector<std::string> compressedFiles;
std::string errorCompressedFile;
};
AsyncData* asyncData = new AsyncData;
asyncData->compressedFiles.push_back(dataFilePath);
_compressedFiles.clear();
std::function<void(void*)> mainThread = [this](void* param) {
AsyncData* asyncData = (AsyncData*)param;
if (asyncData->errorCompressedFile.empty())
{
// 5. Set update state
_updateState = State::UP_TO_DATE;
// 6. Notify finished event
dispatchUpdateEvent(EventAssetsManagerEx::EventCode::UPDATE_FINISHED);
}
else
{
_updateState = State::FAIL_TO_UPDATE;
dispatchUpdateEvent(EventAssetsManagerEx::EventCode::ERROR_DECOMPRESS, "", "Unable to decompress file " + asyncData->errorCompressedFile);
}
delete asyncData;
};
AsyncTaskPool::getInstance()->enqueue(AsyncTaskPool::TaskType::TASK_OTHER, mainThread, (void*)asyncData, [this, asyncData]() {
// Decompress all compressed files
for (auto& zipFile : asyncData->compressedFiles) {
if (!decompressPlaza(zipFile))
{
asyncData->errorCompressedFile = zipFile;
break;
}
_fileUtils->removeFile(zipFile);
}
});
}