zip 파일목록 보여주기 프로그램 작성 2번째 


  • 이번에는 Central directory file header를 이용해서 파일 목록을 보여줘보도록하시죠 

  • end of central directory record 구조체 작성
// Zip end of central directory record - Signature = 0x06054b50
struct _zip_end_central_h
{   
    ushort  number;         // Number of this disk
    ushort  start;          // Disk where central directory starts
    ushort  record_cnt;     // Number of central directory records on this disk
    ushort  totoal_record_cnt;  // Total number of central directory records
    ulong   central_size;   // Size of central directory (bytes)
    ulong   offset;         // Offset of start of central directory
    ushort  comment_len;    // ZIP file comment length (n)
} __attribute__((packed));
typedef struct _zip_end_central_h zip_end_central_h;


  • Central directory file header구조체 작성
// Central directory file header -  signature = 0x02014b50
struct _zip_cetral_h
{
    ushort  ver_m;      // Version made by
    ushort  ver_n;      // Version needed to extract (minimum)
    ushort  flag;       // General purpose bit flag
    ushort  method;     // Compression method
    ushort  time;       // File last modification time
    ushort  date;       // File last modification date
    ulong   crc;        // CRC-32
    ulong   compressed_size;    // Compressed size
    ulong   uncompressed_size;  // Uncompressed size
    ushort  filename_len;       // File name length (n)
    ushort  extra_len;          // Extra field length (m)
    ushort  comment_len;        // File comment length (k)
    ushort  starts;             // Disk number where file starts
    ushort  i_attributes;       // Internal file attributes
    ulong   e_attributes;       // External file attributes
    ulong   relative_offset;    // Relative offset of local file header.
} __attribute__((packed));
typedef struct _zip_cetral_h zip_cetral_h;



  • main 작성
 
1 // test.zip 파일 을 연다.
2 // 파일 위치를 끝으로 이동.
3 // end of central directory records 를 찾을때까지 반복.
4
5 // 못찾았으면 종료.
6 // 찾았다면 centrol directory file header로 이동한다.
7 // 파일 끝까지 반복한다.
8     // 시그너처를 읽는다.
9     // centrol directory signature 가 아니면
10         // break;
11     // centrol directory 구조체를 읽어들인다.
12     // 파일이름을 읽어들인다.
13     // extra data와 file comment를 읽어들인다.
14     // 파일명과 압축된 파일 용량을 출력한다.
15 // 파일을 닫는다.

  • 완전소스
// zipinfo2.c
// http:://fehead.tistory.com
#include <stdio.h>
#include <stdlib.h>

typedef unsigned short  ushort;
typedef unsigned long   ulong;

// Zip end of central directory record - Signature = 0x06054b50
struct _zip_end_central_h
{
        ushort  number;                 // Number of this disk
        ushort  start;                  // Disk where central directory starts
        ushort  record_cnt;             // Number of central directory records on this disk
        ushort  totoal_record_cnt;      // Total number of central directory records
        ulong   central_size;   // Size of central directory (bytes)
        ulong   offset;                 // Offset of start of central directory
        ushort  comment_len;    // ZIP file comment length (n)
} __attribute__((packed));
typedef struct _zip_end_central_h zip_end_central_h;

// Central directory file header -  signature = 0x02014b50
struct _zip_cetral_h
{
        ushort  ver_m;          // Version made by
        ushort  ver_n;          // Version needed to extract (minimum)
        ushort  flag;           // General purpose bit flag
        ushort  method;         // Compression method
        ushort  time;           // File last modification time
        ushort  date;           // File last modification date
        ulong   crc;            // CRC-32
        ulong   compressed_size;        // Compressed size
        ulong   uncompressed_size;      // Uncompressed size
        ushort  filename_len;           // File name length (n)
        ushort  extra_len;                      // Extra field length (m)
        ushort  comment_len;            // File comment length (k)
        ushort  starts;                         // Disk number where file starts
        ushort  i_attributes;           // Internal file attributes
        ulong   e_attributes;           // External file attributes
        ulong   relative_offset;        // Relative offset of local file header.
} __attribute__((packed));
typedef struct _zip_cetral_h zip_cetral_h;


int main()
{
        // test.zip 파일 을 연다.
        FILE *  zip_file = 0;
        zip_file = fopen("test.zip""r");
        if(zip_file == 0)
        {
                perror("fopen:");
                return 0;
        }

        // end of central directory records를 찾는다.
        ulong   signature = 0;
        long    pos = (long)sizeof(zip_end_central_h) + sizeof(signature);
        fseek(zip_file, -pos, SEEK_END);

        fread(&signature, 1sizeof(signature), zip_file);

        // 못찾았으면 종료.
        if(signature != 0x06054b50)
        {
                fprintf(stderr"not found end of central directory records\n");
                return 0;
        }

        // 찾았다면 centrol directory file header로 이동한다.
        zip_end_central_h       e;
        fread(&e, 1sizeof(zip_end_central_h), zip_file);
        fseek(zip_file, e.offset, SEEK_SET);

        // 파일 끝까지 반복한다.
        int i = 0;
        for(i = 0 ; i < e.totoal_record_cnt ; ++i)
        {
                // 시그너처를 읽는다.
                fread(&signature, 1sizeof(signature), zip_file);

                // centrol directory signature 가 아니면
                if(signature != 0x02014b50)
                        break;

                // centrol directory 구조체를 읽어들인다.
                zip_cetral_h    c;
                fread(&c, 1sizeof(c), zip_file);

                // 파일이름을 읽어들인다.
                char * filename = (char *)malloc(c.filename_len + 1);
                fread(filename, 1, c.filename_len, zip_file);
                filename[c.filename_len] = 0;

                // extra data와 file comment를 읽어들인다. 그냥 넘긴다.
                fseek(zip_file, c.extra_len, SEEK_CUR);
                fseek(zip_file, c.comment_len, SEEK_CUR);

                // 파일명과 압축된 파일 용량을 출력한다.
                printf("%s\tCompressed size:%u\t Uncompressed size:%u\n",
                                filename, c.compressed_size, c.uncompressed_size);

                free(filename);

        }
        // 파일을 닫는다.
        fclose(zip_file);

        return 0;
}


  • 결과
$ ./zipinfo2 
aa.txt	Compressed size:16	 Uncompressed size:16
bb.txt	Compressed size:16	 Uncompressed size:16

+ Recent posts