使用Zip Utils 解压文件的操作示例
来源:互联网 发布:元级潜艇模型 淘宝 编辑:程序博客网 时间:2024/05/22 05:21
点此查看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=%d\n"),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=%d\n"),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=%d\n"),pFn,GetLastError()); return nullptr; } return pTmpData;}int _tmain(int argc, _TCHAR* argv[]){ if (argc < 2) { wprintf_s(_T("error:too small arg\ninput like:unzip file pwd,pwd can be null\n ")); return 1; } if (argc > 3) { wprintf_s(_T("error:too many args\ninput like:unzip file pwd,pwd can be null\n ")); 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=%d\n"),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 = %d\n"),ze.name,ze.comp_size,ze.unc_size); pData = CreateUnzipFile(ze.name,ze.unc_size);//创建同名临时文件,默认路径是程序同目录 if (nullptr == pData) { wprintf_s(_T("Unzip failed\n")); 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 %d\n"),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_HDECLARE_HANDLE(HZIP);#endif// An HZIP identifies a zip file that has been openedtypedef 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 解压文件的操作示例
- 使用java实现zip文件的解压
- 解压*.zip.*的文件
- c# 动态操作 zip\rar 文件,压缩解压组件使用
- 使用Objective-Zip解压Zip文件
- 使用Java解压ZIP文件
- Linux下zip文件的压缩与解压操作
- 解压.zip格式的文件
- java使用Apache的ant压缩和解压文件(zip)
- java使用7-zip解压带密码的大文件
- c#操作excel(解压zip文件)
- FIle 文件操作,包括文件的复制、删除以及zip和rar格式的解压操作
- 使用 ZLib 压缩/解压 ZIP 文件
- 使用InfoZip压缩解压zip文件
- 使用 ZLib 压缩/解压 ZIP 文件
- 使用java.util.zip压缩、解压文件
- 使用 ZLib 压缩/解压 ZIP 文件
- 使用 ZLib 压缩/解压 ZIP 文件
- 学习FFmpeg API – 解码视频
- 任意字节对齐的内存分配和释放
- HDU:2571 命运(DP)
- Java网络编程(四) 通过MulticastSocket实现广播
- Apache mina2 用户指南(十三)调试
- 使用Zip Utils 解压文件的操作示例
- Gecco源码分析(一)
- BT3-BT5专题
- 关于ES、PES、PS以及TS码流
- 神经网络学习笔记(六) 广义回归神经网络
- ***没有规则可以创建“XXX”需要的目标“XXX”问题的解决方案
- C语言基础教学——if选择结构(第三课)
- Apache mina2 用户指南(十二)日志过滤器
- 正则表达式进阶