#define ZLIB_WINAPI #include <string> #include <iostream> #include <vector> #include <Shlwapi.h> #include <zip.h> #include <unzip.h> #include <zlib.h>
using namespace std;
#pragma comment(lib, "Shlwapi.lib") #pragma comment(lib, "zlibstat.lib")
class MyZip { private: bool nyAddfiletoZip(zipFile zfile, const std::string& fileNameinZip, const std::string& srcfile) { if (NULL == zfile || fileNameinZip.empty()) { return false; }
int nErr = 0; zip_fileinfo zinfo = { 0 }; tm_zip tmz = { 0 }; zinfo.tmz_date = tmz; zinfo.dosDate = 0; zinfo.internal_fa = 0; zinfo.external_fa = 0;
char sznewfileName[MAX_PATH] = { 0 }; memset(sznewfileName, 0x00, sizeof(sznewfileName)); strcat_s(sznewfileName, fileNameinZip.c_str()); if (srcfile.empty()) { strcat_s(sznewfileName, "\\"); }
nErr = zipOpenNewFileInZip(zfile, sznewfileName, &zinfo, NULL, 0, NULL, 0, NULL, Z_DEFLATED, Z_DEFAULT_COMPRESSION); if (nErr != ZIP_OK) { return false; }
if (!srcfile.empty()) { FILE* srcfp = _fsopen(srcfile.c_str(), "rb", _SH_DENYNO); if (NULL == srcfp) { return false; }
int numBytes = 0; char* pBuf = new char[1024 * 100]; if (NULL == pBuf) { return false; }
while (!feof(srcfp)) { memset(pBuf, 0x00, sizeof(pBuf)); numBytes = fread(pBuf, 1, sizeof(pBuf), srcfp); nErr = zipWriteInFileInZip(zfile, pBuf, numBytes); if (ferror(srcfp)) { break; } }
delete[] pBuf; fclose(srcfp); }
zipCloseFileInZip(zfile);
return true; }
bool nyCollectfileInDirtoZip(zipFile zfile, const std::string& filepath, const std::string& parentdirName) { if (NULL == zfile || filepath.empty()) { return false; }
bool bFile = false; std::string relativepath = ""; WIN32_FIND_DATAA findFileData;
char szpath[MAX_PATH] = { 0 }; if (::PathIsDirectoryA(filepath.c_str())) { strcpy_s(szpath, sizeof(szpath) / sizeof(szpath[0]), filepath.c_str()); int len = strlen(szpath) + strlen("\\*.*") + 1; strcat_s(szpath, len, "\\*.*"); } else { bFile = true; strcpy_s(szpath, sizeof(szpath) / sizeof(szpath[0]), filepath.c_str()); }
HANDLE hFile = ::FindFirstFileA(szpath, &findFileData); if (NULL == hFile) { return false; }
do { if (parentdirName.empty()) relativepath = findFileData.cFileName; else relativepath = parentdirName + "\\" + findFileData.cFileName;
if (findFileData.dwFileAttributes == FILE_ATTRIBUTE_DIRECTORY) { if (strcmp(findFileData.cFileName, ".") != 0 && strcmp(findFileData.cFileName, "..") != 0) { nyAddfiletoZip(zfile, relativepath, "");
char szTemp[MAX_PATH] = { 0 }; strcpy_s(szTemp, filepath.c_str()); strcat_s(szTemp, "\\"); strcat_s(szTemp, findFileData.cFileName); nyCollectfileInDirtoZip(zfile, szTemp, relativepath); } continue; }
char szTemp[MAX_PATH] = { 0 }; if (bFile) { strcpy_s(szTemp, filepath.c_str()); } else { strcpy_s(szTemp, filepath.c_str()); strcat_s(szTemp, "\\"); strcat_s(szTemp, findFileData.cFileName); }
nyAddfiletoZip(zfile, relativepath, szTemp);
} while (::FindNextFileA(hFile, &findFileData));
FindClose(hFile);
return true; }
std::string& replace_all(std::string& str, const std::string& old_value, const std::string& new_value) { while (true) { std::string::size_type pos(0); if ((pos = str.find(old_value)) != std::string::npos) str.replace(pos, old_value.length(), new_value); else break; } return str; }
BOOL CreatedMultipleDirectory(const std::string& direct) { std::string Directoryname = direct; if (Directoryname[Directoryname.length() - 1] != '\\') { Directoryname.append(1, '\\'); }
std::vector< std::string> vpath; std::string strtemp; BOOL bSuccess = FALSE;
for (int i = 0; i < Directoryname.length(); i++) { if (Directoryname[i] != '\\') { strtemp.append(1, Directoryname[i]); } else { vpath.push_back(strtemp); strtemp.append(1, '\\'); } }
std::vector< std::string>::iterator vIter = vpath.begin(); for (; vIter != vpath.end(); vIter++) { bSuccess = CreateDirectoryA(vIter->c_str(), NULL) ? TRUE : FALSE; }
return bSuccess; }
public: bool Compress(const std::string& dirpathName, const std::string& zipfileName, const std::string& parentdirName) { bool bRet = false; zipFile zFile = NULL;
if (!::PathFileExistsA(zipfileName.c_str())) { zFile = zipOpen(zipfileName.c_str(), APPEND_STATUS_CREATE); } else { zFile = zipOpen(zipfileName.c_str(), APPEND_STATUS_ADDINZIP); }
if (NULL == zFile) { return bRet; }
if (nyCollectfileInDirtoZip(zFile, dirpathName, parentdirName)) { bRet = true; }
zipClose(zFile, NULL);
return bRet; }
bool UnCompress(const std::string& strFilePath, const std::string& strTempPath) { int nReturnValue; string tempFilePath; string srcFilePath(strFilePath); string destFilePath;
unzFile unzfile = unzOpen(srcFilePath.c_str()); if (unzfile == NULL) { return false; }
unz_global_info* pGlobalInfo = new unz_global_info; nReturnValue = unzGetGlobalInfo(unzfile, pGlobalInfo); if (nReturnValue != UNZ_OK) { return false; }
unz_file_info* pFileInfo = new unz_file_info; char szZipFName[MAX_PATH] = { 0 }; char szExtraName[MAX_PATH] = { 0 }; char szCommName[MAX_PATH] = { 0 };
for (int i = 0; i < pGlobalInfo->number_entry; i++) { nReturnValue = unzGetCurrentFileInfo(unzfile, pFileInfo, szZipFName, MAX_PATH, szExtraName, MAX_PATH, szCommName, MAX_PATH); if (nReturnValue != UNZ_OK) return false;
string strZipFName = szZipFName;
if (pFileInfo->external_fa == FILE_ATTRIBUTE_DIRECTORY || (strZipFName.rfind('/') == strZipFName.length() - 1)) { destFilePath = strTempPath + "//" + szZipFName; CreateDirectoryA(destFilePath.c_str(), NULL); } else { string strFullFilePath; tempFilePath = strTempPath + "/" + szZipFName; strFullFilePath = tempFilePath;
int nPos = tempFilePath.rfind("/"); int nPosRev = tempFilePath.rfind("\\"); if (nPosRev == string::npos && nPos == string::npos) continue;
size_t nSplitPos = nPos > nPosRev ? nPos : nPosRev; destFilePath = tempFilePath.substr(0, nSplitPos + 1);
if (!PathIsDirectoryA(destFilePath.c_str())) { destFilePath = replace_all(destFilePath, "/", "\\"); int bRet = CreatedMultipleDirectory(destFilePath); }
strFullFilePath = replace_all(strFullFilePath, "/", "\\");
HANDLE hFile = CreateFileA(strFullFilePath.c_str(), GENERIC_WRITE, 0, NULL, OPEN_ALWAYS, FILE_FLAG_WRITE_THROUGH, NULL); if (hFile == INVALID_HANDLE_VALUE) { return false; }
nReturnValue = unzOpenCurrentFile(unzfile); if (nReturnValue != UNZ_OK) { CloseHandle(hFile); return false; }
uLong BUFFER_SIZE = pFileInfo->uncompressed_size; void* szReadBuffer = NULL; szReadBuffer = (char*)malloc(BUFFER_SIZE); if (NULL == szReadBuffer) { break; }
while (TRUE) { memset(szReadBuffer, 0, BUFFER_SIZE); int nReadFileSize = 0;
nReadFileSize = unzReadCurrentFile(unzfile, szReadBuffer, BUFFER_SIZE);
if (nReadFileSize < 0) { unzCloseCurrentFile(unzfile); CloseHandle(hFile); return false; } else if (nReadFileSize == 0) { unzCloseCurrentFile(unzfile); CloseHandle(hFile); break; } else { DWORD dWrite = 0; BOOL bWriteSuccessed = WriteFile(hFile, szReadBuffer, BUFFER_SIZE, &dWrite, NULL); if (!bWriteSuccessed) { unzCloseCurrentFile(unzfile); CloseHandle(hFile); return false; } } }
free(szReadBuffer); } unzGoToNextFile(unzfile); }
delete pFileInfo; delete pGlobalInfo;
if (unzfile) { unzClose(unzfile); }
return true; } };
|