在线观看www成人影院-在线观看www日本免费网站-在线观看www视频-在线观看操-欧美18在线-欧美1级

0
  • 聊天消息
  • 系統消息
  • 評論與回復
登錄后你可以
  • 下載海量資料
  • 學習在線課程
  • 觀看技術視頻
  • 寫文章/發帖/加入社區
會員中心
創作中心

完善資料讓更多小伙伴認識你,還能領取20積分哦,立即完善>

3天內不再提示

如何寫Linux下的tar打包軟件?

Linux愛好者 ? 來源:YongHao寫東西的cache ? 作者:YongHao寫東西的ca ? 2021-03-10 10:44 ? 次閱讀

相信你對 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 《- time()

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 《- time()

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

”, 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

”, 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; i《cur_dir_block-》nentries ; 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

”, filename);

for(int i=1; i《header.nblocks ; 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 《 need_data_blocks; d_block_id++) {

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 下的打包軟件 tar

文章出處:【微信公眾號:Linux愛好者】歡迎添加關注!文章轉載請注明出處。

責任編輯:haq

聲明:本文內容及配圖由入駐作者撰寫或者入駐合作網站授權轉載。文章觀點僅代表作者本人,不代表電子發燒友網立場。文章及其配圖僅供工程師學習之用,如有內容侵權或者其他違規問題,請聯系本站處理。 舉報投訴
  • Linux
    +關注

    關注

    87

    文章

    11465

    瀏覽量

    212837
  • 軟件
    +關注

    關注

    69

    文章

    5121

    瀏覽量

    88962

原文標題:帶你寫一個 linux 下的打包軟件 tar

文章出處:【微信號:LinuxHub,微信公眾號:Linux愛好者】歡迎添加關注!文章轉載請注明出處。

收藏 人收藏

    評論

    相關推薦
    熱點推薦

    Linux文件系統打包及鏡像制作,觸覺智能RK3562開發板演示

    本文介紹Linux開發板文件系統打包及鏡像制作的方法,演示Linux文件系統打包及鏡像制作,適用于想將配置好的系統環境打包成鏡像批量燒錄。觸
    的頭像 發表于 04-28 16:45 ?241次閱讀
    <b class='flag-5'>Linux</b>文件系統<b class='flag-5'>打包</b>及鏡像制作,觸覺智能RK3562開發板演示

    Linux固件燒中的陷阱:文件系統異步寫入引發的問題

    在工業生產中,固件燒是確保產品正常運行的關鍵環節。本文通過一個實際案例,揭示了Linux系統因文件寫入異步性導致的固件燒不完全問題。客戶案例客戶產線上批量生產時,用SD卡進行固件
    的頭像 發表于 03-07 11:34 ?305次閱讀
    <b class='flag-5'>Linux</b>固件燒<b class='flag-5'>寫</b>中的陷阱:文件系統異步寫入引發的問題

    openocd的.cfg的文件如何寫

    各位大佬們,最近想學習一openocd的.cfg的文件如何寫,各位大佬們,有什么入門學習的教程嗎?
    發表于 03-07 09:33

    Linux環境軟件包下載指令是什么呢?

    在windows的env中可以直接使用pkgs —update去下載軟件包,Linux環境這個指令好像不生效,那么Linux環境
    發表于 02-19 07:34

    從零入門Prometheus:構建企業級監控與報警系統的最佳實踐指南

    測試環境 prometheus-2.26.0.linux-amd64.tar.gz下載地址:https://github.com/prometheus/prometheus/releases
    的頭像 發表于 02-10 11:28 ?541次閱讀
    從零入門Prometheus:構建企業級監控與報警系統的最佳實踐指南

    Linux安裝軟件有哪些方法

    Linux安裝軟件,可以有哪些方法? 首先是最簡單的,使用軟件包管理工具。 如果是ubuntu或者debian系統,可以使用apt;如果是紅帽或者centos,可以使用yum。 所
    的頭像 發表于 02-08 09:41 ?530次閱讀

    如何在Linux環境高效安裝部署和配置Elasticsearch

    /CentOS-7-x86_64-DVD-2009.iso elasticsearch-7.10.0-linux-x86_64.tar.gz https://www.elastic.co/cn/downloads/past-releases
    的頭像 發表于 01-16 11:49 ?886次閱讀

    linux服務器穩定性壓?測試?具stress安裝使?介紹

    linux 服務器穩定性壓?測試?具 stress 安裝使?介紹 一、簡介 1、stress?具是Linux下一款壓?測試?具, 可以模擬系統?負載運? , 同時可協助我們進?軟件
    的頭像 發表于 01-15 09:25 ?997次閱讀
    <b class='flag-5'>linux</b><b class='flag-5'>下</b>服務器穩定性壓?測試?具stress安裝使?介紹

    迅為RK3568開發板EMMC鏡像導出打包update.img

    在上一個小節中已經將 EMMC 中的全部分區鏡像進行了導出,而為了方便期間和統一燒,我們一般都需要將這些鏡像文件打包成一個整體的鏡像 update.img,在本小節中將對鏡像打包的過程進行講解
    發表于 12-25 14:57

    Linux文件壓縮打包的各種姿勢

    1.文件打包與壓縮 1.什么是文件壓縮? 將多個文件或目錄合并成為一個特殊的文件。比如: 搬家…腦補畫面 img. 2.為什么要對文件進行壓縮? 當我們在傳輸大量的文件時,通常都會選擇將該文件進行
    的頭像 發表于 12-02 09:25 ?542次閱讀

    一文讀懂BOM管理():BOM結構/實例,PLM中的BOM管理

    BOM管理進階:如何寫一個BOM結構?怎樣開始BOM管理?
    的頭像 發表于 11-13 15:19 ?1500次閱讀
    一文讀懂BOM管理(<b class='flag-5'>下</b>):BOM結構/實例,PLM中的BOM管理

    嵌入式學習-飛凌嵌入式ElfBoard ELF 1板卡-libjpeg庫移植

    打包bin目錄下的所有測試工具。elf@ubuntu:~/work$ cd install/bin/elf@ubuntu:~/work/install/bin$ tar cvjf
    發表于 07-11 08:36

    飛凌嵌入式ElfBoard ELF 1板卡-libjpeg庫移植

    打包bin目錄下的所有測試工具。elf@ubuntu:~/work$ cd install/bin/elf@ubuntu:~/work/install/bin$ tar cvjf
    發表于 07-10 11:42

    ubuntu平臺下安裝ESP32-IDF時,openocd-esp32-linux64-0.10.0-esp32-20190708.tar.gz下載不了的原因?

    下載openocd-esp32-linux64-0.10.0-esp32-20190708.tar.gz,卻始終下載失敗? https://github.com/espressif/openocd-es ... 2-20190708
    發表于 06-25 06:17

    摩托羅拉P200軟件

    摩托羅拉P200軟件摩托羅拉P200軟件
    發表于 06-17 11:53 ?6次下載
    主站蜘蛛池模板: 91麻豆麻豆| 亚洲六月婷婷 | 日本丶国产丶欧美色综合 | 久久久久久久蜜桃 | 亚洲不卡免费视频 | 天天干视频在线 | 日本一区二区三区视频在线观看 | 亚洲香蕉久久一区二区三区四区 | 久久人人爽爽爽人久久久 | 天天操夜 | 天堂网在线资源www种子 | 四虎在线视频 | 激情六月丁香婷婷 | 婷婷综合亚洲 | 国产91丝袜在线播放九色 | 5566精品资源在线播放 | 欧美jizz大又粗 | 精品国产免费一区二区 | 99久久99久久久99精品齐 | 玖玖在线精品 | 操夜夜 | 精品女同同性视频很黄很色 | 亚洲国产福利 | 久久精品午夜视频 | 免费在线黄网 | 日本加勒比高清一本大道 | 精品99久久 | 丁香六月激情综合 | mide-776中文字幕在线 | 欧美性生活一级 | 成人黄网大全在线观看 | 夜夜夜爽bbbb性视频 | 狠狠操狠狠干 | 色婷婷精品综合久久狠狠 | 色欲麻豆国产福利精品 | 色天天综合久久久久综合片 | 伊人天天操 | 2021最新国产成人精品视频 | 亚洲伦理中文字幕一区 | 夜夜草天天干 | 亚洲资源在线观看 |