使用minizip压缩文件

来源:互联网 发布:外资数据 编辑:程序博客网 时间:2024/05/22 17:28

先决条件:

首先下载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 );       
}

原创粉丝点击