c语言提取tar包内容

tar文件:以一定方式将多个文件合并成tar文件,不对文件进行压缩,

tar文件格式 很 简单,每个文件前面+512字节的header,并且将所有文件叠放在一起

header1–file1–header2–file2–header3–file3

解包就是读取文件头得到文件大小,然后读取出文件就行了

提取tar文件并存储

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
#include <stdio.h>
// #include <.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <fcntl.h>
#define min(a,b) (((a) < (b)) ? a : b)

struct posix_tar_header
{
char name[100];
char mode[8];
char uid[8];
char gid[8];
char size[12];
char mtime[12];
char chksum[8];
char typeflag;
char linkname[100];
char magic[6];
char version[2];
char uname[32];
char gname[32];
char devmajor[8];
char devminor[8];
char prefix[155];
};

int main(int argc,char *argv[])
{
if (argc != 2)
{
printf("请输入文件\n");
exit(1);
}
printf("[解压文件: %s\n",argv[1]);
int fd = open(argv[1],O_RDWR);

char buf[1024*4];
int chunk = sizeof(buf);

while(1)
{
read(fd,buf,512);//读取tar header
if (buf[0] == 0)
break;

struct posix_tar_header *phdr = (struct posix_tar_header*)buf;

//从tar header头得到size
char *p = phdr->size;
int f_len = 0;
while(*p)//8进制->10进制
f_len = (f_len * 8) + (*p++ - '0');

int bytes_left = f_len;//此文件大小
int fdout = open(phdr->name,O_CREAT | O_RDWR);
if (fdout == -1)
{
printf(" failed to extract file: %s\n",phdr->name);
printf(" fdout open failed\n");
return 0;
}
printf(" %s (%d bytes)\n",phdr->name,f_len);
while(bytes_left)
{
int iobytes = min(chunk,bytes_left);
//read(fd,buf,iobytes);
read(fd,buf,((iobytes - 1) / 512 + 1) * 512);
write(fdout,buf,iobytes);
bytes_left -= iobytes;
}
close(fdout);
}
close(fd);
printf("done]\n");
return 0;
}

测试:

tar -cvf bao.tar 1.in 2.in 3.in

在这里插入图片描述
./test bao.tar

在这里插入图片描述

tar文件结构csdn