C++获取zip文件列表
// ZipFile.h 
#ifndef ZIPFILE_H #define ZIPFILE_H #include <string> #include <vector> #define ZIP_OK 0 #define ZIP_ERR_OPEN 1 #define ZIP_ERR_WRONG_FILE 2 #define ZIP_ERR_WRONG_HEADER 3 #define BYTE unsigned char #define ui32 unsigned int #define ui16 unsigned short struct FileHeader { ui32 signature; ui16 version_made_by; ui16 version_needed; ui16 bitflags; ui16 comp_method; ui16 lastModFileTime; ui16 lastModFileDate; ui32 crc_32; ui32 comp_size; ui32 uncompr_size; ui16 fname_len; ui16 extra_field_len; ui16 fcomment_len; ui16 disk_num_start; ui16 internal_fattribute; ui32 external_fattribute; ui32 relative_offset; char* file_name; char* extra_field; char* file_comment; }; class CZipFile { private: public: CZipFile(); CZipFile(std::string); virtual ~CZipFile(); void ResetContent(void); std::string GetFileName(void); void SetFileName(std::string); bool OpenFile(void); int GetFilesNumber(void); FileHeader * GetFileAttributes(int); private: void ReadCentralDirectory(BYTE * data,long len); int ReadFileHeader(BYTE * data, FileHeader * hdr); ui32 ReadValue(unsigned char * buf, int nbits); std::string m_FileName; std::vector<void*> m_FileAttributes; }; #endif /*ZIPFILE_H */
//
// ZipFile.cpp : implementation file
//
#include <stdio.h> #include <assert.h> #include <string.h> #include "ZipFile.h" using namespace std; ///////////////////////////////////////////////////////////////////////////// // CZipFile CZipFile::CZipFile() { m_FileName=""; } CZipFile::CZipFile(string fn) { m_FileName = fn; } CZipFile::~CZipFile() { ResetContent(); } void CZipFile::ResetContent(void) { for(int i=0;i<GetFilesNumber();i++) delete(GetFileAttributes(i)); m_FileAttributes.clear(); m_FileName=""; } string CZipFile::GetFileName(void) { return m_FileName; } void CZipFile::SetFileName(string fn) { m_FileName = fn; } int CZipFile::GetFilesNumber(void) { return (m_FileAttributes.size()); } bool CZipFile::OpenFile(void) { if(m_FileName=="") return ZIP_ERR_OPEN; //read all the file data FILE * fp; fp=fopen(m_FileName.c_str(),"rb"); if(fp==NULL) return ZIP_ERR_OPEN; fseek(fp,0,SEEK_END); long siz=ftell(fp); fseek(fp,0,SEEK_SET); BYTE *buf=new BYTE[siz]; ui32 n= fread((void*) buf,(unsigned int)siz,1,fp); fclose(fp); //local file header signature control to check the file correctiveness if(*((ui32*)buf)!=0x04034b50) return ZIP_ERR_WRONG_FILE; ReadCentralDirectory(buf,siz); return ZIP_OK; } void CZipFile::ReadCentralDirectory(BYTE * data,long len) { /*read the central Directory Data Structure; data contains the zipped archive; return the number of files read*/ BYTE * tmp; //search the signature tmp=data; ui32 * tmp2; tmp2= (ui32 *)tmp; len-=4; while((*tmp2)!=0x02014b50 && len) { tmp++; tmp2= (ui32 *)tmp; len--; } //retrieve the FileHeader for each file int siz; do { FileHeader fhdr; siz = ReadFileHeader(tmp, &fhdr); if(siz) { FileHeader *pfhdr = new(FileHeader); *pfhdr=fhdr; m_FileAttributes.push_back(pfhdr); } tmp+=siz; }while(siz!=0); } int CZipFile::ReadFileHeader(BYTE * data, FileHeader * hdr) { /*Name: int CZipFile::ReadFileHeader(BYTE * data, CString* stData) /*It read the file header in the Central Directory Structure Return the number of bytes read; if the stream does not contain a valid local_file_header 0 is returned and the stream pointer (f) is not modified st is filled with all the data; */ BYTE * origdata=data; // FileHeader hdr; //fill the values into the file_header structure hdr->signature = (ui32) ReadValue(data ,32); if(hdr->signature!=0x02014b50) return 0; //no further file hdr->version_made_by = (ui16) ReadValue(data+4 ,16); hdr->version_needed = (ui16) ReadValue(data+6 ,16); hdr->bitflags = (ui16) ReadValue(data+8 ,16); hdr->comp_method = (ui16) ReadValue(data+10,16); hdr->lastModFileTime = (ui16) ReadValue(data+12,16); hdr->lastModFileDate = (ui16) ReadValue(data+14,16); hdr->crc_32 = (ui32) ReadValue(data+16,32); hdr->comp_size = (ui32) ReadValue(data+20,32); hdr->uncompr_size = (ui32) ReadValue(data+24,32); hdr->fname_len = (ui16) ReadValue(data+28,16); hdr->extra_field_len = (ui16) ReadValue(data+30,16); hdr->fcomment_len = (ui16) ReadValue(data+32,16); hdr->disk_num_start = (ui16) ReadValue(data+34,16); hdr->internal_fattribute = (ui16) ReadValue(data+36,16); hdr->external_fattribute = (ui32) ReadValue(data+38,32); hdr->relative_offset = (ui32) ReadValue(data+42,32); data+=46; if(hdr->fname_len>0) { char *fn; fn=new (char[hdr->fname_len+1]); strncpy(fn,(char*)data,hdr->fname_len); fn[hdr->fname_len]='\0'; hdr->file_name = fn; data+=hdr->fname_len; } if(hdr->extra_field_len>0) { char *fn; fn=new (char[hdr->extra_field_len+1]); strncpy(fn,(char*)data,hdr->extra_field_len); fn[hdr->extra_field_len]='\0'; hdr->extra_field = fn; data += hdr->extra_field_len; } //file comment if(hdr->fcomment_len>0) { char *fn; fn=new (char[hdr->fcomment_len+1]); strncpy(fn,(char*)data,hdr->fcomment_len); fn[hdr->fcomment_len]='\0'; hdr->file_comment = fn; data += hdr->extra_field_len; } return (data-origdata); } ui32 CZipFile::ReadValue(unsigned char * buf, int nbits) { /*Name: void ReadValue(char*buf, int nbits) /*Return the value read from the buffer of size nbits; */ ui32 value = 0; switch (nbits) { case (8): value = (ui32)*(buf); break; case(16): value = (((ui32)*(buf+1))<<8)+(ui32)*(buf); break; case(24): value = (((ui32)*(buf+2))<<16)+(((ui32)*(buf+1))<<8)+((ui32)*(buf)); break; case(32): value = (((ui32)*(buf+3))<<24)+(((ui32)*(buf+2))<<16)+(((ui32)*(buf+1))<<8)+((ui32)*(buf)); break; default: assert(1); break; } return(value); } FileHeader *CZipFile::GetFileAttributes(int index) { if(index<0 || index >m_FileAttributes.size()) return NULL; else return((FileHeader *)m_FileAttributes.at(index)); }
//main.cpp
#include <stdio.h> #include "ZipFile.h" int main(int argc , char* argv[]) { if(2 != argc) { printf("zipFile must provide.\n"); return 0; } CZipFile zipTest; zipTest.SetFileName(argv[1]); zipTest.OpenFile(); for(int i = 0;i< zipTest.GetFilesNumber();i++) { printf("%s\n", zipTest.GetFileAttributes(i)->file_name); } return 0; }