Chinaunix首页 | 论坛 | 博客
  • 博客访问: 5833507
  • 博文数量: 671
  • 博客积分: 10010
  • 博客等级: 上将
  • 技术积分: 7310
  • 用 户 组: 普通用户
  • 注册时间: 2006-07-14 09:56
文章分类

全部博文(671)

文章存档

2011年(1)

2010年(2)

2009年(24)

2008年(271)

2007年(319)

2006年(54)

我的朋友

分类: C/C++

2008-08-28 13:07:24

CZipFile: a Lite Zip Archive File Viewer
Rating: none

Arcangelo Bruna ()
March 4, 2003


Environment: VC6 SP4

Introduction

CZipFile is a lite library that allows you to get information about a zip archive. It is not able to decompress the files, but just retrieves the contents—the file name, file size, and so on.

I developed it because I need a lite way to list the zip file's contents on a list view. But all the code I found on the Internet was really huge, allowing me to decode the files. I needed a very small application, so I made my own class. The downloadable code was compiled for Windows 98 and 2000. I think that it should be compiled by all Windows platforms.

Overview of a ZIP File

The information was retrieved in the PKWARE's appnote.txt file; that can be found on the Internet. The information we need is contained in the [central directory] structure. It contains, file by file, all the information about the file features (file name, compressed and uncompressed file size, date and time, ...) and the compression options (compression method, password protection, ...)

So, in order to retrieve the file's attribute, the following passes must be performed:

  1. Be sure that the file is a valid ZIP archive
  2. Look for the [central directory] header
  3. Decode all the information for each file

They were implemented, as in the following:

  1. The ZIP file correctiveness can be tested (but not necessarily) by reading the first four bytes of the zipped file. They are the "local file header signature" and must be the value 0x04034b50.
  2. The [central directory] header is signed by a 4-byte code called "central file header signature" with the value 0x02014b50. It can be found looking for such code in the stream.
  3. The [central directory] has the following structure:
          [file header 1]
    
          .
          .
          .
    
          [file header n]
    
          [digital signature]
    
    We need to decode just the [file header x] blocks until no other [file header] is found.

Each [file header] starts with a signature (0x02014b50), so it is really simple to find it in the stream.

Each file header data was encapsulated in a structure. An array stores all the file headers.

struct FileHeader
{
  DWORD signature;
  WORD version_made_by;
  WORD version_needed;
  WORD bitflags;
  WORD comp_method;
  WORD lastModFileTime;
  WORD lastModFileDate;
  DWORD crc_32;
  DWORD comp_size;
  DWORD uncompr_size;
  WORD fname_len;
  WORD extra_field_len;
  WORD fcomment_len;
  WORD disk_num_start;
  WORD internal_fattribute;
  DWORD external_fattribute;
  DWORD relative_offset;
  char* file_name;
  char* extra_field;
  char* file_comment;
};

The original application uses just the file_name attribute to fill a list view. However, the demo application uses the comp_size (compressed size in bytes), the uncompr_size (uncompressed size in bytes), the lastModFileDate, and the lastModFileTime for the file's date and time, and the bit 0 of the bitflags, indicating the password protection flag.

Class Description

The core of the paper is the CZipFile class that encapsulates all the operations. It is defined as the following:

class CZipFile
{
// Attributes
private:
  CString   m_FileName;
  CPtrArray m_FileAttributes;

//interface
public:
  CZipFile();
  CZipFile(CString);
  virtual ~CZipFile();
  void    ResetContent(void);

  CString      GetFileName(void);
  void         SetFileName(CString);
  BOOL         OpenFile(void);
  int          GetFilesNumber(void);
  FileHeader * GetFileAttributes(int);

// inner operations
private:
  void    ReadCentralDirectory(BYTE * data,long len);
  int     ReadFileHeader(BYTE * data, FileHeader * hdr);
  DWORD   ReadValue(unsigned char * buf, int nbits);
};

The public interface allows us to set and to retrieve the ZIP file name (respectively, SetFileName and GetFileName), to open the file (OpenFile, that reads all the data), to reset the class content information (ResetContent), to retrieve the number of files inserted in the zip archive (GetFilesNumber), and to retrieve all the information of each file (GetFileAttributes).

All the other variables/functions are hidden. They are used for storing the ZIP information and reading the Central Directory structure.

Using the Class

To use the CZipFile class in your project, you need to add the following files:

zipstruct.h contains the FileHeader structure
ZipFile.h contains the CZipFile class definition
ZipFile.cpp contains the CZipFile class implementation

The Demo Project

The included application is just a demo on how to use the class. It allows you to open a zipped archive and list its contents (the file name) in a list control. Each file's attributes can be displayed by simply clicking it in the list control.

Downloads

Download demo project - 105 Kb
阅读(1224) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~