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;
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;
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 // 파일을 닫는다.
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, 1, sizeof(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, 1, sizeof(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, 1, sizeof(signature), zip_file);
// centrol directory signature 가 아니면
if(signature != 0x02014b50)
break;
// centrol directory 구조체를 읽어들인다.
zip_cetral_h c;
fread(&c, 1, sizeof(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;
}
// 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, 1, sizeof(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, 1, sizeof(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, 1, sizeof(signature), zip_file);
// centrol directory signature 가 아니면
if(signature != 0x02014b50)
break;
// centrol directory 구조체를 읽어들인다.
zip_cetral_h c;
fread(&c, 1, sizeof(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