본문 바로가기
C++, MFC

[C++, MFC] 압축, 압축 해제 라이브러리 / XZip, XUnzip 사용방법

by dev_drive 2022. 12. 29.
반응형

 

 

GitHub - yuanjia1011/XZip-XUnZip

Contribute to yuanjia1011/XZip-XUnZip development by creating an account on GitHub.

github.com

우선 라이브러리 원본의 출처는 CodeProject인데 버그도 있고 로그인이 필요해서

위 깃허브 사이트에서 받는것을 추천드리며

 

깃허브에 있는 소스도 unzip할때 파일의 UTC타임을 변환해 주는 부분에서 버그가 좀 있어서 수정했는데

원하시는 분들은 아래 파일 받으시길 바랍니다. 

XZip.zip
0.08MB

 

MFC를 사용하는 경우 XZip.cpp, XUnzip.cpp 최상단에 미리 컴파일된 헤더인 pch.h나 stdafx.h를 추가해주면 됩니다. 

 

 


※ 파일 압축

BOOL CZipProjectDlg::DoZipFile(CString sTargetDir, CString sZipDir)
{
	if (GetFileAttributes(sTargetDir) == 0xFFFFFFFF)
		return FALSE;

	CStringArray strArray, strErrorArray;
	HZIP hz = CreateZip(sZipDir.GetBuffer(0), 0, ZIP_FILENAME); // 관리자 권한이 필요한 경로면 실패할 수 있음. 
	if (hz)
	{
#ifdef _UNICODE
		ZIPENTRYW ze;
#else
		ZIPENTRY ze;
#endif
		memset(&ze, 0, sizeof(ze));

		CFileFind	ff;
		CString		sSearchFile;
		CString		sTargetFile, sTemp;

		strArray.Add(sTargetDir); 
		while (strArray.GetCount() > 0)
		{
			sSearchFile.Format(_T("%s\\*.*"), strArray.GetAt(0));
			BOOL res = ff.FindFile(sSearchFile);
			while (res)
			{
				res = ff.FindNextFile();
				if (!ff.IsDots() && ff.IsDirectory()) 
				{
					strArray.Add(ff.GetFilePath());
					sTargetFile = ff.GetFilePath();

					sTemp.Format(_T("%s\\"), sTargetDir);
					sTargetFile.Replace(sTemp, _T(""));

					if (ZipAdd(hz, sTargetFile, 0, 0, ZIP_FOLDER) != ZR_OK) 
						strErrorArray.Add(ff.GetFilePath());  // 폴더 추가 오류
				}
				else if (!ff.IsDots())
				{
					sTargetFile = ff.GetFilePath();
 					if(sZipDir == sTargetFile)  // 자기 자신은 제외
 						continue;

					sTemp.Format(_T("%s\\"), sTargetDir);
					sTargetFile.Replace(sTemp, _T(""));

					if (ZipAdd(hz, sTargetFile, (ff.GetFilePath().GetBuffer(0)), 0, ZIP_FILENAME) != ZR_OK) 
						strErrorArray.Add(ff.GetFilePath());  // 파일 추가 오류
				}
			}
			ff.Close();
			strArray.RemoveAt(0);
		}

		CloseZip(hz);
	}
	else 
		return FALSE;

	return TRUE;
}

 

 

※ 파일 압축 해제

BOOL CZipProjectDlg::DoUnzipFile(CString sTargetDir, CString sUnzipDir)
{
	if (GetFileAttributes(sTargetDir) == 0xFFFFFFFF)
		return FALSE;

	if (GetFileAttributes(sUnzipDir) == 0xFFFFFFFF)
		CreateDirectory(sUnzipDir, NULL);

	ZRESULT zr = 0;
	TCHAR szCurrentdir[MAX_PATH];
	GetCurrentDirectory(MAX_PATH, szCurrentdir);
	SetCurrentDirectory(sUnzipDir);

	HZIP hz = OpenZip((TCHAR*)(LPCTSTR)sTargetDir, 0, ZIP_FILENAME);
	if (hz)
	{
#ifdef _UNICODE
		ZIPENTRYW ze;
#else
		ZIPENTRY ze;
#endif
		ZeroMemory(&ze, sizeof(ze));
		GetZipItem(hz, -1, &ze);

		int numitems = ze.index;
		for (int i = 0; i < numitems; i++)
		{
			zr = GetZipItem(hz, i, &ze);
			if (zr == ZR_OK)
			{
				zr = UnzipItem(hz, i, ze.name, 0, ZIP_FILENAME);
 				if ((ze.attr & FILE_ATTRIBUTE_DIRECTORY) == 0)
 				{
					// 압축 해제 파일 내역을 출력하고 싶은 경우 ze.name으로 ..
 				}
			}
		}
		CloseZip(hz);
	}

	SetCurrentDirectory(szCurrentdir);
	return TRUE;
}

 

 

※ 함수 사용은 각각 아래처럼 하면 되겠습니다. 

DoZipFile(_T("C:\\Temp"), _T("C:\\Temp\\Temp2.zip"));   // 압축
DoUnzipFile(_T("C:\\Temp\\Temp2.zip"), _T("C:\\Temp\\Temp2"));   // 압축 해제

 

 

※ 참고로 엄청 오래된 소스라 속도가 빠른편은 아니니 간단한 작업인 경우만 사용하시고 다양한 zip라이브러리들이 존재하니 상황에 맞게 사용하시길 바랍니다. 

 

반응형

댓글