我是靠谱客的博主 傲娇钢笔,最近开发中收集的这篇文章主要介绍使用Zip Utils 解压文件的操作示例,觉得挺不错的,现在分享给大家,希望可以做个参考。

概述

点此查看Zip Utils介绍


函数说明

OpenZip()
1.HZIP OpenZip(const TCHAR *fn, const char *password);
参数fn文件路径,相对和绝对路径应该都可以,支持unicode格式
password是解压的密码,可以为空,只需传入参数0即可。但是遗憾的是,密码只支持ascii格式,没办法,只好自己封装了两个函数用于单字节和宽字节之间互相转换
2.HZIP OpenZip(void *z,unsigned int len, const char *password);
参数z表示一个数据地址,len表示长度,可以用来直接从内存里读取zip数据
password同上
HZIP OpenZipHandle(HANDLE h, const char *password);
参数h表示一个句柄,表示可以从文件/管道等内核对象句柄中加载zip数据
password同上

GetZipItem()获取item信息
1.ZRESULT GetZipItem(HZIP hz, int index, ZIPENTRY *ze);
用来获取一个HZIP对象的信息,该对象需通过OpenZip函数调用返回。
2.ZIPENTRY结构体用以存储每一个item信息部分:
typedef struct
{
int index; // 表示在zip文件中的索引,based 0
TCHAR name[MAX_PATH]; // 表示在zip文件中的名称
DWORD attr; // 文件属性.
FILETIME atime,ctime,mtime;// 访问时间, 创建时间, 最后更改时间
long comp_size; // 压缩后的大小
long unc_size; // 原始文件大小(如果获取失败则有可能是-1)
} ZIPENTRY;
3.执行成功返回ZR_OK,返回其他表示失败,可通过FormatZipMessage()来获取详细错误信息
UnzipItem()
1.ZRESULT UnzipItem(HZIP hz, int index, const TCHAR *fn);
2.ZRESULT UnzipItem(HZIP hz, int index, void *z,unsigned int len);
3.ZRESULT UnzipItemHandle(HZIP hz, int index, HANDLE h);
给定一个item的index,将其解压到以下地方:
1.管道/文件 调用UnzipItemHandle(hz,index,handle);
2.内存块 调用UnzipItem(hz,index,buf,len);
3.文件by name 调用UnzipItem(hz,index,filename);
SetUnzipBaseDir()
设置默认的解压目录


基本操作如下所示:

//
#include "stdafx.h"
#include <windows.h>
#include <tchar.h>
#include <stdio.h>
#include "unzip.h"

TCHAR * Char2Wchar(char* pSrc)  //将单字节字符串转换为宽字节字符串
{
    static TCHAR wchDest[256] = {0};
    int iReqLen = MultiByteToWideChar(CP_ACP,0,pSrc,-1,nullptr,0);
    if (iReqLen > 256)  return wchDest; //返回空
    MultiByteToWideChar(CP_ACP,0,pSrc,-1,wchDest,256 * sizeof(TCHAR));
    return wchDest;
}


CHAR * Wchar2Char(TCHAR * pSrc) //将宽字节字符串转换为单字节字符串
{
    static CHAR chDest[256] = {0};
    BOOL    bUsedDef = FALSE;
    int iReqLen = WideCharToMultiByte(CP_ACP,0,pSrc,-1,nullptr,0,nullptr,&bUsedDef);
    if (iReqLen > 256)  return chDest;//返回空
    WideCharToMultiByte(CP_ACP,0,pSrc,-1,chDest,256,nullptr,&bUsedDef);
    return chDest;
}

VOID    ReleaseUnzipFile(PVOID pData)
{
    if (nullptr != pData)
    {
        UnmapViewOfFile(pData);
    }
}

VOID * CreateUnzipFile(TCHAR *pFn,size_t nFileSize)
{
    HANDLE hFile = CreateFile(pFn,GENERIC_READ|GENERIC_WRITE,FILE_SHARE_READ,nullptr,CREATE_ALWAYS,FILE_ATTRIBUTE_NORMAL,nullptr);
    if (INVALID_HANDLE_VALUE == hFile)
    {
        wprintf_s(_T("%s Create File()Failed,ErrCode=%dn"),pFn,GetLastError());
        return nullptr ;
    }

    DWORD dwFileSize = nFileSize;//预期文件大小
    HANDLE hMapFile = CreateFileMapping(hFile,nullptr,PAGE_READWRITE,0,dwFileSize,nullptr);
    CloseHandle(hFile);
    if (nullptr == hMapFile)
    {
        wprintf_s(_T("%s CreateFileMapping() Failed,ErrCode=%dn"),pFn,GetLastError());
        return nullptr;
    }
    PVOID pTmpData = MapViewOfFile(hMapFile,FILE_MAP_ALL_ACCESS,0,0,0);

    CloseHandle(hMapFile);
    if (nullptr == pTmpData)    
    {
        wprintf_s(_T("%s MapViewOfFile() Failed,ErrCode=%dn"),pFn,GetLastError());
        return nullptr;
    }

    return pTmpData;
}

int _tmain(int argc, _TCHAR* argv[])
{
    if (argc < 2)
    {
        wprintf_s(_T("error:too small argninput like:unzip file pwd,pwd can be nulln ")); 
        return 1;
    }

    if (argc > 3)
    {
        wprintf_s(_T("error:too many argsninput like:unzip file pwd,pwd can be nulln ")); 
        return 1;
    }
    TCHAR* pFileName = nullptr;
    TCHAR* pWPwd = nullptr;
    CHAR* pPwd = nullptr;
    pFileName = argv[1];
    if (argc == 3)
    {
        pWPwd = argv[2];    //get password
        pPwd = Wchar2Char(pWPwd);
    }

    HZIP hz = OpenZip(pFileName,pPwd);  //打开zip文件,pwd可以为空
    ZIPENTRY    ze ;
    ZRESULT zrt = GetZipItem(hz,-1,&ze);
    if (zrt != ZR_OK)
    {
        wprintf_s(_T("Unzip failed!err=%dn"),zrt); return 1;
    }
    PVOID pData = nullptr;
    int numitems = ze.index;
    TCHAR chErr[256] = {0};
    wprintf_s(_T("Start Unzip...n"));
    int iUnzipCnt = 0;
    for (int ii = 0;ii < numitems;ii++)
    {
        ZIPENTRY ze; GetZipItem(hz,ii,&ze); // 获取每一个文件详细信息
        UnzipItem(hz, ii, ze.name);         // e.g. the item's name.
        wprintf_s(_T("Unzip file: %s ,comp size = %d, uncomp size = %dn"),ze.name,ze.comp_size,ze.unc_size);

        pData = CreateUnzipFile(ze.name,ze.unc_size);//创建同名临时文件,默认路径是程序同目录
        if (nullptr == pData)
        {
            wprintf_s(_T("Unzip failedn"));    continue;
        }
        zrt = UnzipItem(hz,ii,pData,ze.unc_size);//解压到pdata中
        if (ZR_OK != zrt)
        {
            FormatZipMessage(zrt,chErr,256);
            wprintf_s(chErr);
            wprintf_s(_T("n"));
        }
        else
        {
            iUnzipCnt ++;
        }

        ReleaseUnzipFile(pData);    //关闭映射对象
    }

    CloseZip(hz); 
    wprintf_s(_T("Unzip finished,%d files ,success unzip %dn"),numitems,iUnzipCnt);

    return 0;
}

说明
1.本例中采用内核文件映射的方式,通过CreateUnzipFile() 预先创建了一个文件,如果解压失败,并不会删除该文件。此处需要注意。
2.unzip提供的函数如果带有ZRESULT返回值,则可以通过FormatZipMessage()函数来得到详细的错误信息
3.需要注意的是,Zip文件打成成功后,必须要调用CloseZip来关闭。类似于内核对象的操作。

以下是unzip.h文件中对以上函数详细解释:

#ifndef _unzip_H
#define _unzip_H

// UNZIPPING functions -- for unzipping.
// This file is a repackaged form of extracts from the zlib code available
// at www.gzip.org/zlib, by Jean-Loup Gailly and Mark Adler. The original
// copyright notice may be found in unzip.cpp. The repackaging was done
// by Lucian Wischik to simplify and extend its use in Windows/C++. Also
// encryption and unicode filenames have been added.


#ifndef _zip_H
DECLARE_HANDLE(HZIP);
#endif
// An HZIP identifies a zip file that has been opened

typedef DWORD ZRESULT;
// return codes from any of the zip functions. Listed later.

typedef struct
{ int index;                 // index of this file within the zip
  TCHAR name[MAX_PATH];      // filename within the zip
  DWORD attr;                // attributes, as in GetFileAttributes.
  FILETIME atime,ctime,mtime;// access, create, modify filetimes
  long comp_size;            // sizes of item, compressed and uncompressed. These
  long unc_size;             // may be -1 if not yet known (e.g. being streamed in)
} ZIPENTRY;


HZIP OpenZip(const TCHAR *fn, const char *password);
HZIP OpenZip(void *z,unsigned int len, const char *password);
HZIP OpenZipHandle(HANDLE h, const char *password);
// OpenZip - opens a zip file and returns a handle with which you can
// subsequently examine its contents. You can open a zip file from:
// from a pipe:             OpenZipHandle(hpipe_read,0);
// from a file (by handle): OpenZipHandle(hfile,0);
// from a file (by name):   OpenZip("c:\test.zip","password");
// from a memory block:     OpenZip(bufstart, buflen,0);
// If the file is opened through a pipe, then items may only be
// accessed in increasing order, and an item may only be unzipped once,
// although GetZipItem can be called immediately before and after unzipping
// it. If it's opened in any other way, then full random access is possible.
// Note: pipe input is not yet implemented.
// Note: zip passwords are ascii, not unicode.
// Note: for windows-ce, you cannot close the handle until after CloseZip.
// but for real windows, the zip makes its own copy of your handle, so you
// can close yours anytime.

ZRESULT GetZipItem(HZIP hz, int index, ZIPENTRY *ze);
// GetZipItem - call this to get information about an item in the zip.
// If index is -1 and the file wasn't opened through a pipe,
// then it returns information about the whole zipfile
// (and in particular ze.index returns the number of index items).
// Note: the item might be a directory (ze.attr & FILE_ATTRIBUTE_DIRECTORY)
// See below for notes on what happens when you unzip such an item.
// Note: if you are opening the zip through a pipe, then random access
// is not possible and GetZipItem(-1) fails and you can't discover the number
// of items except by calling GetZipItem on each one of them in turn,
// starting at 0, until eventually the call fails. Also, in the event that
// you are opening through a pipe and the zip was itself created into a pipe,
// then then comp_size and sometimes unc_size as well may not be known until
// after the item has been unzipped.

ZRESULT FindZipItem(HZIP hz, const TCHAR *name, bool ic, int *index, ZIPENTRY *ze);
// FindZipItem - finds an item by name. ic means 'insensitive to case'.
// It returns the index of the item, and returns information about it.
// If nothing was found, then index is set to -1 and the function returns
// an error code.

ZRESULT UnzipItem(HZIP hz, int index, const TCHAR *fn);
ZRESULT UnzipItem(HZIP hz, int index, void *z,unsigned int len);
ZRESULT UnzipItemHandle(HZIP hz, int index, HANDLE h);
// UnzipItem - given an index to an item, unzips it. You can unzip to:
// to a pipe:             UnzipItemHandle(hz,i, hpipe_write);
// to a file (by handle): UnzipItemHandle(hz,i, hfile);
// to a file (by name):   UnzipItem(hz,i, ze.name);
// to a memory block:     UnzipItem(hz,i, buf,buflen);
// In the final case, if the buffer isn't large enough to hold it all,
// then the return code indicates that more is yet to come. If it was
// large enough, and you want to know precisely how big, GetZipItem.
// Note: zip files are normally stored with relative pathnames. If you
// unzip with ZIP_FILENAME a relative pathname then the item gets created
// relative to the current directory - it first ensures that all necessary
// subdirectories have been created. Also, the item may itself be a directory.
// If you unzip a directory with ZIP_FILENAME, then the directory gets created.
// If you unzip it to a handle or a memory block, then nothing gets created
// and it emits 0 bytes.
ZRESULT SetUnzipBaseDir(HZIP hz, const TCHAR *dir);
// if unzipping to a filename, and it's a relative filename, then it will be relative to here.
// (defaults to current-directory).


ZRESULT CloseZip(HZIP hz);
// CloseZip - the zip handle must be closed with this function.

unsigned int FormatZipMessage(ZRESULT code, TCHAR *buf,unsigned int len);
// FormatZipMessage - given an error code, formats it as a string.
// It returns the length of the error message. If buf/len points
// to a real buffer, then it also writes as much as possible into there.


// These are the result codes:
#define ZR_OK         0x00000000     // nb. the pseudo-code zr-recent is never returned,
#define ZR_RECENT     0x00000001     // but can be passed to FormatZipMessage.
// The following come from general system stuff (e.g. files not openable)
#define ZR_GENMASK    0x0000FF00
#define ZR_NODUPH     0x00000100     // couldn't duplicate the handle
#define ZR_NOFILE     0x00000200     // couldn't create/open the file
#define ZR_NOALLOC    0x00000300     // failed to allocate some resource
#define ZR_WRITE      0x00000400     // a general error writing to the file
#define ZR_NOTFOUND   0x00000500     // couldn't find that file in the zip
#define ZR_MORE       0x00000600     // there's still more data to be unzipped
#define ZR_CORRUPT    0x00000700     // the zipfile is corrupt or not a zipfile
#define ZR_READ       0x00000800     // a general error reading the file
#define ZR_PASSWORD   0x00001000     // we didn't get the right password to unzip the file
// The following come from mistakes on the part of the caller
#define ZR_CALLERMASK 0x00FF0000
#define ZR_ARGS       0x00010000     // general mistake with the arguments
#define ZR_NOTMMAP    0x00020000     // tried to ZipGetMemory, but that only works on mmap zipfiles, which yours wasn't
#define ZR_MEMSIZE    0x00030000     // the memory size is too small
#define ZR_FAILED     0x00040000     // the thing was already failed when you called this function
#define ZR_ENDED      0x00050000     // the zip creation has already been closed
#define ZR_MISSIZE    0x00060000     // the indicated input file size turned out mistaken
#define ZR_PARTIALUNZ 0x00070000     // the file had already been partially unzipped
#define ZR_ZMODE      0x00080000     // tried to mix creating/opening a zip 
// The following come from bugs within the zip library itself
#define ZR_BUGMASK    0xFF000000
#define ZR_NOTINITED  0x01000000     // initialisation didn't work
#define ZR_SEEK       0x02000000     // trying to seek in an unseekable file
#define ZR_NOCHANGE   0x04000000     // changed its mind on storage, but not allowed
#define ZR_FLATE      0x05000000     // an internal error in the de/inflation code





// e.g.
//
// SetCurrentDirectory("c:\docs\stuff");
// HZIP hz = OpenZip("c:\stuff.zip",0);
// ZIPENTRY ze; GetZipItem(hz,-1,&ze); int numitems=ze.index;
// for (int i=0; i<numitems; i++)
// { GetZipItem(hz,i,&ze);
//   UnzipItem(hz,i,ze.name);
// }
// CloseZip(hz);
//
//
// HRSRC hrsrc = FindResource(hInstance,MAKEINTRESOURCE(1),RT_RCDATA);
// HANDLE hglob = LoadResource(hInstance,hrsrc);
// void *zipbuf=LockResource(hglob);
// unsigned int ziplen=SizeofResource(hInstance,hrsrc);
// HZIP hz = OpenZip(zipbuf, ziplen, 0);
//   - unzip to a membuffer -
// ZIPENTRY ze; int i; FindZipItem(hz,"file.dat",true,&i,&ze);
// char *ibuf = new char[ze.unc_size];
// UnzipItem(hz,i, ibuf, ze.unc_size);
// delete[] ibuf;
//   - unzip to a fixed membuff -
// ZIPENTRY ze; int i; FindZipItem(hz,"file.dat",true,&i,&ze);
// char ibuf[1024]; ZRESULT zr=ZR_MORE; unsigned long totsize=0;
// while (zr==ZR_MORE)
// { zr = UnzipItem(hz,i, ibuf,1024);
//   unsigned long bufsize=1024; if (zr==ZR_OK) bufsize=ze.unc_size-totsize;
//   totsize+=bufsize;
// }
//   - unzip to a pipe -
// HANDLE hwrite; HANDLE hthread=CreateWavReaderThread(&hwrite);
// int i; ZIPENTRY ze; FindZipItem(hz,"sound.wav",true,&i,&ze);
// UnzipItemHandle(hz,i, hwrite);
// CloseHandle(hwrite);
// WaitForSingleObject(hthread,INFINITE);
// CloseHandle(hwrite); CloseHandle(hthread);
//   - finished -
// CloseZip(hz);
// // note: no need to free resources obtained through Find/Load/LockResource
//
//
// SetCurrentDirectory("c:\docs\pipedzipstuff");
// HANDLE hread,hwrite; CreatePipe(&hread,&hwrite,0,0);
// CreateZipWriterThread(hwrite);
// HZIP hz = OpenZipHandle(hread,0);
// for (int i=0; ; i++)
// { ZIPENTRY ze;
//   ZRESULT zr=GetZipItem(hz,i,&ze); if (zr!=ZR_OK) break; // no more
//   UnzipItem(hz,i, ze.name);
// }
// CloseZip(hz);
//
//




// Now we indulge in a little skullduggery so that the code works whether
// the user has included just zip or both zip and unzip.
// Idea: if header files for both zip and unzip are present, then presumably
// the cpp files for zip and unzip are both present, so we will call
// one or the other of them based on a dynamic choice. If the header file
// for only one is present, then we will bind to that particular one.
ZRESULT CloseZipU(HZIP hz);
unsigned int FormatZipMessageU(ZRESULT code, TCHAR *buf,unsigned int len);
bool IsZipHandleU(HZIP hz);
#ifdef _zip_H
#undef CloseZip
#define CloseZip(hz) (IsZipHandleU(hz)?CloseZipU(hz):CloseZipZ(hz))
#else
#define CloseZip CloseZipU
#define FormatZipMessage FormatZipMessageU
#endif



#endif // _unzip_H

End
By Jared Kin

最后

以上就是傲娇钢笔为你收集整理的使用Zip Utils 解压文件的操作示例的全部内容,希望文章能够帮你解决使用Zip Utils 解压文件的操作示例所遇到的程序开发问题。

如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(33)

评论列表共有 0 条评论

立即
投稿
返回
顶部