Chinaunix首页 | 论坛 | 博客
  • 博客访问: 1638399
  • 博文数量: 197
  • 博客积分: 10046
  • 博客等级: 上将
  • 技术积分: 1983
  • 用 户 组: 普通用户
  • 注册时间: 2006-08-07 12:36
个人简介

在外企做服务器开发, 目前是项目经理, 管理两个server开发的项目。不做嵌入式好久了。

文章分类
文章存档

2011年(2)

2010年(6)

2009年(18)

2008年(30)

2007年(100)

2006年(41)

分类: LINUX

2007-05-10 13:34:49

其实tar的原理很简单: comment by bob 2006-8-3 11:48
tar文件的构成:
tar文件最顶端是512字节的header ,里面记录了对应的file的stat信息,比如uid,gid,mode等等
然后是文件正文内容

如果tar里面包含了其他的文件的话, 又是一个header ,剩下的又是文件正文
..........................

最后tar文件的末尾是 最少 1024个字节的 '\0' 表示tar结尾。当然一般情况下是 10240个bytes 0
--------------------------------------------------------------------------------------------
tar 源码分析:
因为基础上面的结构,所以tar的source code 就比较容易理解了:
tar 采用了block和record的概念
record = 20 个 block (default)

源码里面用20个block的连续的buffer来存储tar fd中的内容,当然一旦这20个block没用,就会flush,又从
tar fd中读10240 个字节到这20个blocks中来。

其中最重要就是 current_header , 是最开始 20个blocks中的第一个,对应了 tar_stat_info->header
如果想了解tar文件包含的文件信息, 就可以读取这个header (调用print_header可以打印出来)

如果要从tar文件中extract某个file ,也很简单, 只需要从第二个block开始读即可了,一直读current_stat_info->stat->st_size
个字节就可以了(因为我们的tar文件中只含有一个file,所以不必考虑后面的 10240个 '\0' 了

标准的tar生成的tar包的size总是 10240的倍数,所以一个tar包,的最小大小总是 10240 ,即使一个file很小。
 
--
 
去年的时候,根据备份的需要的,我把tar精简了一下,适合嵌入式应用
做成了库德形式, 

类似这样:

OpenArchive();//Open or Create one Archive File
GetElementInfo();//Get information of one element in the archive including timestamp, type, size.
DeleteElement();//Delete one element from one archive.
AddFileToArchive();//Add one element to one archive.
CloseArchive();//Close one archive.
FindFirstElement();//Get information of first element from the archive.
ExtractElement(); //Extract one element from the archive.

---
简单的测试程序:

#include "app.h"
#include "archive.h"

//example.c

int main(int argc, char **argv
)
{
    
struct stat stat_file
;
    
int fd = -1
;
    
int rc = 0
;
    
    
S_archive_stat_info  *ft = NULL
;
    
//fd = OpenArchive("/tmp/1/kk.tar.gz","w");
    
fd = OpenArchive(argv[2],"w"
);
    
printf("has called OpenArchive () \n"
);
    
printf("in main fd=%d\n",fd
);
    if(
fd < 0
)  {
        
//fatal_error("can't open /var/bob.tar.gz\n");
        
return -1
;
    }
    
printf("sizeof  S_archive_stat_info =%d\n",sizeof(S_archive_stat_info
));    
    
printf("size of tar_stat_info = %d\n",sizeof(struct tar_stat_info
));
    
    
stat(argv[1] , &stat_file
);
    
printf("stat.st_mtime = %ld\n",stat_file.st_mtime
);
    
printf("open OK \n"
);
    
    
    
rc = AddFileToArchive(fd,argv[1
]);
    
printf("rc = %d\n",rc
);
    if(
rc < 0
) {
        
//有可能是磁盘满了,要判断这个错误
        //直接返回即可,不必CloseArchive()了,  因为处理处理代码,我已经加上了。
        
return -1
;
    }
    
CloseArchive(fd
);

    return
0
;
        
}

 

__________________
阅读(4333) | 评论(2) | 转发(0) |
给主人留下些什么吧!~~

bob_zhang20042008-07-15 20:56:09

没有, 从来没想过。

chinaunix网友2008-07-02 10:49:50

写的非常好,请问你有没有把tar移植到windows平台下呢?