cocos2dx解压zip

cocos集成了解压的功能,但为方便我单独提取出来。

ZipArchive类是放在libcocos2d/extension/assetsmanager目录下的

ZipArchive.h

#ifndef _ZIPARCHIVE_H_
#define _ZIPARCHIVE_H_

#include "cocos2d.h"
#include "cocos-ext.h"
NS_CC_EXT_BEGIN
class CC_EX_DLL ZipArchive
{
public:
	ZipArchive();
	~ZipArchive();
		
	bool decompress(const std::string &zip);
	
private:
	std::string basename(const std::string& path) const;
	FileUtils *_fileUtils;
};
NS_CC_EXT_END
#endif

ZipArchive.cpp

#include "ZipArchive.h"
#include "stdio.h"
#include "sys/stat.h"

#ifdef MINIZIP_FROM_SYSTEM
#include <minizip/unzip.h>
#else // from our embedded sources
#include "unzip.h"
#endif

NS_CC_EXT_BEGIN

#define BUFFER_SIZE    8192
#define MAX_FILENAME   512

ZipArchive::ZipArchive()
{
	_fileUtils = FileUtils::getInstance();
}


ZipArchive::~ZipArchive()
{
}

bool ZipArchive::decompress(const std::string &zip)
{
	// Find root path for zip file
	size_t pos = zip.find_last_of("/\\");
	if (pos == std::string::npos)
	{
		log("AssetsManagerEx : no root path specified for zip file %s\n", zip.c_str());
		return false;
	}
	const std::string rootPath = zip.substr(0, pos + 1);

	// Open the zip file
	unzFile zipfile = unzOpen(FileUtils::getInstance()->getSuitableFOpen(zip).c_str());
	if (!zipfile)
	{
		log("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)
	{
		log("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)
		{
			log("AssetsManagerEx : can not read compressed file info\n");
			unzClose(zipfile);
			return false;
		}
		const 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
				log("AssetsManagerEx : can not create directory %s\n", fullPath.c_str());
				unzClose(zipfile);
				return false;
			}
		}
		else
		{
			// Create all directories in advance to avoid issue
			std::string dir = basename(fullPath);
			if (!_fileUtils->isDirectoryExist(dir)) {
				if (!_fileUtils->createDirectory(dir)) {
					// Failed to create directory
					log("AssetsManagerEx : can not create directory %s\n", fullPath.c_str());
					unzClose(zipfile);
					return false;
				}
			}
			// Entry is a file, so extract it.
			// Open current file.
			if (unzOpenCurrentFile(zipfile) != UNZ_OK)
			{
				log("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)
			{
				log("AssetsManagerEx : can not create decompress destination file %s (errno: %d)\n", fullPath.c_str(), errno);
				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)
				{
					log("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)
			{
				log("AssetsManagerEx : can not read next file for decompressing\n");
				unzClose(zipfile);
				return false;
			}
		}
	}

	unzClose(zipfile);
	_fileUtils->removeFile(zip);
	return true;
}

std::string ZipArchive::basename(const std::string& path) const
{
	size_t found = path.find_last_of("/\\");

	if (std::string::npos != found)
	{
		return path.substr(0, found);
	}
	else
	{
		return path;
	}
}

NS_CC_EXT_END

调用方法:

#include "extension/assets-manager/ZipArchive.h"
void zzip()
{
	//获取文件路径  
	std::string str = FileUtils::getInstance()->getWritablePath() + "Resources.zip";
	const char* file_path = str.c_str();
	log("external file path = %s", file_path);

	cocos2d::extension::ZipArchive * zip = new cocos2d::extension::ZipArchive();
	
	zip->decompress(str);
}



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值