先决条件:
首先下载minizip 的库文件http://www.winimage.com/zLibDll/minizip.html
其次需要添加头文件支持 #include "../../zip.h" #include "../../unzip.h"
另外,要添加库文件的支持 UnzipUD.lib
几个重要的结构
目标文件结构:zipFile zf;
待压缩文件的结构:zip_fileinfo zi;//zip文件信息
几个重要的函数:
打开目标文件:zf = zipOpen(W2CA(strZipFile),0);
添加新的压缩文件:zipOpenNewFileInZip(...)//添加新的压缩文件
将数据写入目标文件:zipWriteInFileInZip (zf,buf,size_read);//写入目标文件中
关闭目标文件:zipClose(zf,NULL);//关闭目标文件
网络资源:
http://www.codeproject.com/KB/files/zip_utils.aspx
http://www.codeproject.com/KB/stl/zipstream.aspx
http://blog.csdn.net/yyyzlf/archive/2009/11/19/4833667.aspx
http://ty263.spaces.live.com/blog/cns!AEDC97760A4C885F!156.entry
http://www.vckbase.com/english/code/misc/mapizip.shtml.htm
附例:
void CScribbleDoc::OnFileSendZippedMail()
{
ASSERT_VALID(this);
CString strMessage;
CString strZipFile;
int errclose = ZIP_OK;
int err=0;
BOOL bModified = IsModified(); //remember original modified flag.
CString strOldName = m_strPathName;
CString strDir;
#ifndef NO_COLESERVERDOC
ASSERT(m_bRemember);
LPSTORAGE lpOrigStg = m_lpRootStg;
m_lpRootStg = NULL;
#endif
TRY
{
#ifndef NO_COLESERVERDOC
m_bRemember = FALSE;
#endif
CWaitCursor wait;
TCHAR szTempName[_MAX_PATH];
TCHAR szPath[_MAX_PATH];
BOOL bRemoveTemp = FALSE;
CString strFile;
TCHAR szDrive[_MAX_DRIVE],szDir[_MAX_DIR], szName[_MAX_FNAME], szExt[_MAX_EXT];
VERIFY(GetTempPath(_countof(szPath), szPath) != 0);
if (m_strPathName.IsEmpty() || IsModified())
{
// save to temporary path.
VERIFY(GetTempFileName(szPath, _T("afx"), 0, szTempName) != 0);
BOOL bResult = DoSave(szTempName, FALSE);
if (!bResult)
{
//We could not save the temp file. Disk full? Not enough privileges?
AfxFormatString1(strMessage, AFX_IDP_FAILED_IO_ERROR_WRITE,szTempName);
THROW (new CFileException);
}
bRemoveTemp = TRUE;
strFile = m_strTitle;
if (m_strTitle.Find('.') == -1) // no extension.
{
CString strExt;
CDocTemplate* pTemplate = GetDocTemplate();
if (pTemplate != NULL && pTemplate->GetDocString(strExt, CDocTemplate::filterExt))
{
strFile += strExt;
}
}
}
else
{
// use actual file since it isn't modified.
lstrcpyn(szTempName, m_strPathName, _countof(szTempName));
_tsplitpath(m_strPathName,NULL,NULL,szName, szExt);
strFile = CString(szName)+ CString(szExt);
}
zipFile zf;
//We try to create a temporary file in the temp-directory, delete it and create a directory with
//the same name and use that for our newly created ZIP-File:
VERIFY(GetTempFileName(szPath, _T("afx"), 0, strZipFile.GetBufferSetLength(_MAX_PATH+32) ) != 0);
strZipFile.ReleaseBuffer();
CFile::Remove(strZipFile);
if (!CreateDirectory(strZipFile,NULL))
{
//Huh, our process has been preempted and someone else created a file or directory with our temp name?
//Are we not allowed to create this directory? Not enough space to create this directory?
//Get out of this hell!
AfxFormatString1(strMessage, AFX_IDP_FAILED_ACCESS_WRITE,strZipFile);
THROW (new CFileException);
}
strDir = strZipFile; //save the temp directory in a variable so we can delete the directory afterwards
strZipFile+=CString(_T("//"))+strFile;
_tsplitpath(strZipFile,szDrive,szDir,szName, szExt);
_tmakepath(strZipFile.GetBufferSetLength(_MAX_PATH+32),szDrive,szDir,szName, _T("zip"));
strZipFile.ReleaseBuffer();
#ifdef UNICODE
USES_CONVERSION;
zf = zipOpen(W2CA(strZipFile),0);
#else
zf = zipOpen(strZipFile,0);
#endif
FILE * fin;
void* buf=NULL;
int size_buf=0;
size_buf = WRITEBUFFERSIZE;
buf = (void*)malloc(size_buf);
if (!buf)
{
//Not enough memory.
strMessage.LoadString(AFX_IDS_MEMORY_EXCEPTION);
THROW (new CMemoryException);
}
int size_read;
zip_fileinfo zi;
int opt_compress_level=Z_BEST_COMPRESSION;
//Best compression to save bandwidth at a maximum.
zi.tmz_date.tm_sec = zi.tmz_date.tm_min = zi.tmz_date.tm_hour =
zi.tmz_date.tm_mday = zi.tmz_date.tm_min = zi.tmz_date.tm_year = 0;
zi.dosDate = 0;
zi.internal_fa = 0;
zi.external_fa = 0;
filetime(szTempName,&zi.dosDate);
err = zipOpenNewFileInZip(zf,
#ifdef UNICODE
W2CA(strFile),
#else
strFile,
#endif
&zi,NULL,0,NULL,0,NULL /* comment*/,(opt_compress_level != 0) ? Z_DEFLATED : 0,opt_compress_level);
ASSERT(err == ZIP_OK);
if (err != ZIP_OK)
{
TRACE1("error in opening %s in zipfile/n",strFile);
AfxFormatString1(strMessage, AFX_IDP_FAILED_IO_ERROR_WRITE,strFile);
THROW (new CFileException); //if we would not return we would use an uninitialized fin variable
}
else
{
fin = _tfopen(szTempName,_T("rb"));
if (fin==NULL)
{
err=ZIP_ERRNO;
TRACE1("error in opening %s for reading/n",szTempName);
strMessage.LoadString(AFX_IDP_FAILED_TO_OPEN_DOC);
THROW (new CFileException);
}
}
do
{
err = ZIP_OK;
size_read = fread(buf,1,size_buf,fin);
if (size_read < size_buf)
if (feof(fin)==0)
{
//Seems like we could not read from the temp name.
AfxFormatString1(strMessage, AFX_IDP_FAILED_IO_ERROR_READ, szTempName);
AfxMessageBox(strMessage);
strMessage.Empty();
err = ZIP_ERRNO;
}
if (err==ZIP_OK && size_read>0)
{
err = zipWriteInFileInZip (zf,buf,size_read);
if (err<0)
{
//We could not write the file in the ZIP-File for whatever reason.
AfxFormatString1(strMessage, AFX_IDP_FAILED_IO_ERROR_WRITE,strZipFile);
AfxMessageBox(strMessage);
strMessage.Empty();
}
}
}
while (err==ZIP_OK && size_read>0);
fclose(fin);
errclose = zipClose(zf,NULL);
if (bRemoveTemp)
CFile::Remove(szTempName);
free (buf);
}
CATCH_ALL(e)
{
SetModifiedFlag(bModified);
m_strPathName = strOldName;
#ifndef NO_COLESERVERDOC
m_lpRootStg = lpOrigStg;
m_bRemember = TRUE;
#endif
if (!strMessage.IsEmpty())
{
AfxMessageBox(strMessage);
return;
}
else
THROW_LAST();
}
END_CATCH_ALL
#ifndef NO_COLESERVERDOC
m_lpRootStg = lpOrigStg;
m_bRemember = TRUE;
#endif
m_strPathName = strZipFile;
if (errclose != ZIP_OK && err==ZIP_OK)
{
//We could not close the ZIP-File
AfxFormatString1(strMessage, AFX_IDP_FAILED_IO_ERROR_WRITE,strZipFile);
AfxMessageBox(strMessage);
}
else if (err==ZIP_OK) //if err!=ZIP_OK, something in creating the zip file went wrong, we already had a message box.
OnFileSendMail(); //yes, everything went the right way up to now. Now invoke the MFC MAPI call OnFileSendMail().
//After we have cheated the MFC OnFileSendMail() call with a ZIP-File instead of a real document,
//we can reset everything to the previously saved values:
SetModifiedFlag(bModified);
m_strPathName = strOldName;
//From now on we don't care if calls succeed. Other apps may have our files or directories open, who knows?
if (_tcslen(strZipFile))
CFile::Remove(strZipFile);
if (_tcslen(strDir))
RemoveDirectory( strDir );
}