日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 运维知识 > linux >内容正文

linux

Linux打包软件版本带时间,带你写一个 linux 下的打包软件 tar

發布時間:2025/3/8 linux 28 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Linux打包软件版本带时间,带你写一个 linux 下的打包软件 tar 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

相信你對 linux 的?.tar.gz?有點熟悉,這就是先 tar 打包(.tar 后綴),再對此?tar?文件用?gzip?壓縮(.tar.gz)的后綴名。

值得注意的是,?tar?不是壓縮軟件,它只做把一堆文件/文件夾打包到一個文件(tar 文件)里的事情,而文件聯系,文件權限,相對的路徑等都會給你保存好。一開始設計是?tar?跟?gzip?只做一件事情,各司其事,后來發現太麻煩了,于是就把壓縮功能整合到 tar 里了。

-?Create?a?gzipped?archive:

tar?czf?target.tar.gz?file1?file2?file3

最近學習 OS 時寫了一個類似?tar?的項目,那么今天就趁熱打鐵簡單說一下如何寫一個打包軟件,這個軟件會將重復的文件內容通過 md5 比較,復用舊的內容。

基本單位 block

block?可以理解為文件系統的最小單位,分別有以下類型:

?directory block,文件夾 block,存儲文件夾 meta 信息;

?file block,文件 block,存儲文件 meta 信息;

?data block,只用來存文件內容;

Directory block,注意的是 entry 里要有 fileindex 來存儲重復文件的 name 的下標。同時,給 項目一個 root dir。

typedef?struct?{

char????????name[SIFS_MAX_NAME_LENGTH];?//?name?of?the?directory

time_t????????modtime;????//?time?last?modified?

uint32_t????????nentries;//?文件夾內的文件/文件夾數量

struct?{

SIFS_BLOCKID????blockID;????//?subdirectory?或者?file?的?blockID

uint32_t????fileindex;????//?重復文件的不同名字

}?entries[SIFS_MAX_ENTRIES];

}?SIFS_DIRBLOCK;

文件 Block,length?就是有多少 bytes 的文件內容,之后用來算有多少個?data block,firstblockID?記錄第一個數據 block 的 id,nfiles?記錄有多少重復內容的文件數量了,filenames?就是重復此文件 block 的文件內容的文件名字。

typedef?struct?{

time_t????????modtime;????//?time?first?file?added?

size_t????????length;????????//?length?of?files'?contents?in?bytes

unsigned?char????md5[MD5_BYTELEN];//the?MD5?cryptographic?digest?(a?summary)?of?the?files'?contents

SIFS_BLOCKID????firstblockID;//?the?block?number?(blockID)?of?the?files'?first?data-block

uint32_t????????nfiles;????????//?n?files?with?identical?contents

char????????filenames[SIFS_MAX_ENTRIES][SIFS_MAX_NAME_LENGTH];//?an?array?of?each?same?file's?name?and?its?modification?time.

}?SIFS_FILEBLOCK;

bitmaps數組,記錄了每個 block 的類型,有:文件、文件夾以及data block 三種類型。

通用函數

就讓大家看看關鍵函數好了:

讀 tar 后的文件的 meta 頭,記錄了 block 的大小( blocksize) 以及多少個 blocks。

void?read_vol_header(FILE?*vol,?SIFS_VOLUME_HEADER?*header){

fread(header,?sizeof(SIFS_VOLUME_HEADER),?1,?vol);

printf("header->blocksize?%zu,?header->nblocks?%u\n",?header->blocksize?,?header->nblocks);

}

bitmap,每次操作 tar 文件都要讀的。

void?read_bitmap(FILE?*vol,?SIFS_BIT?*bitmap,?int?nblocks){

int?size?=?nblocks?*?sizeof(SIFS_BIT);

fread(bitmap,?size,?1,?vol);

}

root_block?同理,讀和寫啥東西都要從 root block、root dir 出發。

void?read_root_block(FILE?*vol,?SIFS_DIRBLOCK?*dirblock){

fread(dirblock,?sizeof(SIFS_DIRBLOCK),?1,?vol);

printf("read_root_block?finish,?dirblock.name:?%s,?dirblock.entrieds:?%d,?dirblock.modtime?%ld\n",?dirblock->name,?dirblock->nentries,dirblock->modtime);

}

路徑嘛,你懂的,./sifs_put volumn ~/res.txt /dirB/subdirB/subsubdir/newfileB,要讀的內容可以靠 read 函數解決,但是寫到 tar 文件里的就要手動解析遞歸查路徑了。

void?read_route_names(char*?pathname,?char**?route_names,?int?*route_cnt)?{

char?*dir;

char?*pathname_to_split?=?copyStr(pathname);

strcpy(pathname_to_split,?pathname);

while?((dir?=?strsep(&pathname_to_split,?"/"))?!=?NULL)?{

route_names[*route_cnt]?=?copyStr(dir);

(*route_cnt)++;

}

}

以上幾乎是?mkdir,rmdir,writefile,readfile,putfile?等等操作都要做的。

實現

然后,應該舉一個 readfile 的例子就可以做代表了。

int?recursive_dirinfo(SIFS_DIRBLOCK?*cur_dir_block,?char?**route_names,?int?route_name_p,?int?route_cnt);

實現:

int?recursive_dirinfo(SIFS_DIRBLOCK?*cur_dir_block,?char?**route_names,?int?route_name_p,?int?route_cnt){

for(int?i=0;?inentries?;?i++)?{

int?blockid?=?cur_dir_block->entries[i].blockID;

if(bitmap[blockid]==SIFS_DIR)?{

SIFS_DIRBLOCK?dirblock;

int?start?=?sizeof(SIFS_VOLUME_HEADER)?+?header.nblocks*sizeof(SIFS_BIT);

read_dir_block(vol,?&dirblock,?blockid?*?blocksize,?start);

if(strcmp(dirblock.name,?route_names[route_name_p])?==?0)?{

if(route_name_p+2?==?route_cnt)?{

return?do_read_file(cur_dir_block,?route_names[route_name_p+1],?blockid);

}

return?recursive_dirinfo(&dirblock,?route_names,?route_name_p+1,?route_cnt);

}

}

}

return?1;

}

以``./sifs_put volumn ~/res.txt /dirB/subdirB/subsubdir/newfileB?為例子,如果遞歸找到?subsubdir`這個文件夾 block,進行相應操作:

?寫文件就往 bitmap 一直找沒有用過的 block,夠寫文件就寫進去,文件夾更新一下信息。

?讀文件就是根據此文件夾 block,找里面的?newfileB

int?do_read_file(SIFS_DIRBLOCK?*parent_dir,?char?*filename,??int?parent_dir_block){

printf("do_find_file_info,?filename?%s\n",?filename);

for(int?i=1;?i

SIFS_FILEBLOCK?fileblock;

if(bitmap[i]==SIFS_FILE)?{

int?start?=?sizeof(SIFS_VOLUME_HEADER)?+?header.nblocks*sizeof(SIFS_BIT);

read_file_block(vol,?&fileblock,?i?*?blocksize,?start);

*nbytes?=?fileblock.length;

int?need_data_blocks?=?*nbytes?/?header.blocksize;

if(strcmp(fileblock.filenames[0],??filename)?==?0)?{

for(int?d_block_id?=?fileblock.firstblockID;?d_block_id?-?i?-1?

read_data_block(vol,?(char*)(*data)+(d_block_id?-?i?-1),?blocksize,?d_block_id?*?header.blocksize,?start);

}

return?0;

}

}

}

return?1;

}

而真實的 tar 自然更復雜,還要記錄用戶權限、用戶、group文件等等:

struct?posix_header

{???????????????????????/*?byte?offset?*/

char?name[100];???????/*???0?*/???文件名

char?mode[8];?????????/*?100?*/???用戶權限

char?uid[8];??????????/*?108?*/???user?id

char?gid[8];??????????/*?116?*/???group?id

char?size[12];????????/*?124?*/???文件大小

char?mtime[12];???????/*?136?*/???修改時間

char?chksum[8];???????/*?148?*/???校驗值

char?typeflag;????????/*?156?*/???文件類型標志

char?linkname[100];???/*?157?*/???符號鏈接指向

char?magic[6];????????/*?257?*/

char?version[2];??????/*?263?*/

char?uname[32];???????/*?265?*/???user?name

char?gname[32];???????/*?297?*/???group?name

char?devmajor[8];?????/*?329?*/???設備文件?major

char?devminor[8];?????/*?337?*/???設備文件?minor

char?prefix[155];?????/*?345?*/

/*?500?*/

};

文件類型標志定義,包含了所有?Unix?系統中的文件類型

#define?REGTYPE??'0'????????????/*?regular?file?*/

#define?LNKTYPE??'1'????????????/*?link?*/

#define?SYMTYPE??'2'????????????/*?reserved?*/

#define?CHRTYPE??'3'????????????/*?character?special?*/

#define?BLKTYPE??'4'????????????/*?block?special?*/

#define?DIRTYPE??'5'????????????/*?directory?*/

#define?FIFOTYPE?'6'????????????/*?FIFO?special?*/

#define?CONTTYPE?'7'????????????/*?reserved?*/

概覽如此,寫起來其實有點煩 - = -,有興趣的讀者可以寫寫。

總結

以上是生活随笔為你收集整理的Linux打包软件版本带时间,带你写一个 linux 下的打包软件 tar的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。