哈哈哈哈哈操欧洲电影,久草网在线,亚洲久久熟女熟妇视频,麻豆精品色,久久福利在线视频,日韩中文字幕的,淫乱毛视频一区,亚洲成人一二三,中文人妻日韩精品电影

0
  • 聊天消息
  • 系統(tǒng)消息
  • 評論與回復(fù)
登錄后你可以
  • 下載海量資料
  • 學(xué)習(xí)在線課程
  • 觀看技術(shù)視頻
  • 寫文章/發(fā)帖/加入社區(qū)
會員中心
創(chuàng)作中心

完善資料讓更多小伙伴認(rèn)識你,還能領(lǐng)取20積分哦,立即完善>

3天內(nèi)不再提示

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

Linux愛好者 ? 來源:YongHao寫東西的cache ? 作者:YongHao寫東西的ca ? 2021-03-10 10:44 ? 次閱讀
加入交流群
微信小助手二維碼

掃碼添加小助手

加入工程師交流群

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

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

- Create a gzipped archive:

tar czf target.tar.gz file1 file2 file3

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

基本單位 block

block 可以理解為文件系統(tǒng)的最小單位,分別有以下類型:

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

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

?data block,只用來存文件內(nèi)容;

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

typedef struct {

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

time_t modtime; // time last modified 《- time()

uint32_t nentries;// 文件夾內(nèi)的文件/文件夾數(shù)量

struct {

SIFS_BLOCKID blockID; // subdirectory 或者 file 的 blockID

uint32_t fileindex; // 重復(fù)文件的不同名字

} entries[SIFS_MAX_ENTRIES];

} SIFS_DIRBLOCK;

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

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數(shù)組,記錄了每個 block 的類型,有:文件、文件夾以及data block 三種類型。

通用函數(shù)

就讓大家看看關(guān)鍵函數(shù)好了:

讀 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 出發(fā)。

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,要讀的內(nèi)容可以靠 read 函數(shù)解決,但是寫到 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 等等操作都要做的。

實現(xiàn)

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

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

實現(xiàn):

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,進行相應(yīng)操作:

?寫文件就往 bitmap 一直找沒有用過的 block,夠?qū)懳募蛯戇M去,文件夾更新一下信息。

?讀文件就是根據(jù)此文件夾 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 自然更復(fù)雜,還要記錄用戶權(quán)限、用戶、group文件等等:

struct posix_header

{ /* byte offset */

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

char mode[8]; /* 100 */ 用戶權(quán)限

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 */ 文件類型標(biāo)志

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 */ 設(shè)備文件 major

char devminor[8]; /* 337 */ 設(shè)備文件 minor

char prefix[155]; /* 345 */

/* 500 */

};

文件類型標(biāo)志定義,包含了所有 Unix 系統(tǒng)中的文件類型

#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 */

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

原文標(biāo)題:帶你寫一個 linux 下的打包軟件 tar

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

責(zé)任編輯:haq

聲明:本文內(nèi)容及配圖由入駐作者撰寫或者入駐合作網(wǎng)站授權(quán)轉(zhuǎn)載。文章觀點僅代表作者本人,不代表電子發(fā)燒友網(wǎng)立場。文章及其配圖僅供工程師學(xué)習(xí)之用,如有內(nèi)容侵權(quán)或者其他違規(guī)問題,請聯(lián)系本站處理。 舉報投訴
  • Linux
    +關(guān)注

    關(guān)注

    88

    文章

    11803

    瀏覽量

    219455
  • 軟件
    +關(guān)注

    關(guān)注

    69

    文章

    5348

    瀏覽量

    91843

原文標(biāo)題:帶你寫一個 linux 下的打包軟件 tar

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

收藏 人收藏
加入交流群
微信小助手二維碼

掃碼添加小助手

加入工程師交流群

    評論

    相關(guān)推薦
    熱點推薦

    Linux系統(tǒng)配置FCB-EV9520L與LVDS轉(zhuǎn)USB3.0編碼采集模塊教程

    Linux系統(tǒng)上運行LVDS轉(zhuǎn)USB3.0編碼采集模塊涉及幾個關(guān)鍵步驟,包括Linux環(huán)境配置、硬件連接、軟件安裝與配置以及測試。以下是一個基本的指南
    的頭像 發(fā)表于 03-04 16:05 ?161次閱讀
    <b class='flag-5'>Linux</b>系統(tǒng)<b class='flag-5'>下</b>配置FCB-EV9520L與LVDS轉(zhuǎn)USB3.0編碼采集模塊教程

    linux的壓縮和解壓操作

    什么不同呢? 不同之處在于: 1) 一般情況,小文件使用gzip來壓縮,大文件使用bzip2來壓縮;2) bzip2 比 gzip 的壓縮率更高。 3、 目錄和多級目錄的解壓和壓縮用 tar
    發(fā)表于 12-23 06:56

    【飛凌OK-T153 開發(fā)板試用】SDK初試

    SDK初試 編繹環(huán)境 硬件: x86_64虛擬機 軟件: ubuntu 18.04 x64 SDK解壓 tar jxvf OKT153-linux-sdk.tar.bz2.0* >
    發(fā)表于 11-14 05:17

    你覺得哪個軟件verilog體驗最好?有什么優(yōu)勢?

    你覺得哪個軟件verilog體驗最好?有什么優(yōu)勢?請在評論區(qū)留言跟大家分享一吧。
    發(fā)表于 11-10 07:47

    Linux搭建平臺

    起因:本人用IDE感覺好不方便,所以配置了相關(guān)的Linux環(huán)境,Linx配置環(huán)境文檔看得有點亂,索性整理了一。 環(huán)境是zsh,用bash的可以稍微改一。主要下載了nuclei-sdk
    發(fā)表于 11-05 09:00

    linux中使用env時如何下載軟件包?

    在windows的env中可以直接使用pkgs —update去下載軟件包,Linux環(huán)境這個指令好像不生效,那么Linux環(huán)境
    發(fā)表于 10-11 09:23

    dist打包好的工程,還能用env工具進行配置嗎?

    就是我在BSP里面用scons —dist打包好一個工程后,把工程放到其它路徑進行項目開發(fā),中間需要用menuconfig進行配置,發(fā)現(xiàn)打不開了,想是不是打包出來的工程就無法配置了,請教一各位這種情況一般是怎么處理的?是重新
    發(fā)表于 09-24 08:18

    聊聊 Webpack 那些安全事兒:打包風(fēng)險與防護小技巧

    Webpack 作為前端工程化的核心工具,幾乎成為現(xiàn)代 Web 應(yīng)用打包的標(biāo)配。它通過模塊合并、代碼壓縮、依賴管理等功能提升開發(fā)效率,但也因配置復(fù)雜、代碼混淆等特性,潛藏著諸多安全風(fēng)險。本文結(jié)合實戰(zhàn)
    的頭像 發(fā)表于 09-02 10:22 ?863次閱讀
    聊聊 Webpack 那些安全事兒:<b class='flag-5'>打包</b>風(fēng)險與防護小技巧

    【米爾NXP i.MX 91開發(fā)板評測】移植和運行RT-Linux,實時性能測試

    echo \"下載RT補丁...\" cd ~/workspace/myir-imx-linux wget -O patches-6.6.36-rt35.tar.xz https
    發(fā)表于 09-01 10:11

    FLASH燒/編程白皮書

    白皮書:如何燒Flash——不同場景不同需求的選擇認(rèn)識Flash?NAND vs. NOR如何燒/編程不同方案比較
    發(fā)表于 07-28 16:05 ?0次下載

    【HZ-RK3568開發(fā)板免費體驗】系統(tǒng)燒

    開發(fā)過程中也是常用的該方式。 筆者本文將講解單個統(tǒng)一固件燒的方式,關(guān)于多個分區(qū)鏡像燒將在系統(tǒng)移植講解。 值得注意的是,通過統(tǒng)一固件解包/打包工具,可以把統(tǒng)一固件解包為多個分區(qū)鏡像,也可以將多個分區(qū)
    發(fā)表于 07-25 09:40

    linux環(huán)境 軟件啟動失敗怎么解決?

    anyway. /usr/lib/x86_64-linux-gnu/libproxy/libpxbackend-1.0.so: undefined symbol
    發(fā)表于 06-23 07:37

    dist打包好的工程,還能用env工具進行配置嗎?

    就是我在BSP里面用scons —dist打包好一個工程后,把工程放到其它路徑進行項目開發(fā),中間需要用menuconfig進行配置,發(fā)現(xiàn)打不開了,想是不是打包出來的工程就無法配置了,請教一各位這種情況一般是怎么處理的?是重新
    發(fā)表于 06-13 07:59

    打包機數(shù)據(jù)采集遠(yuǎn)程監(jiān)控系統(tǒng)方案

    在現(xiàn)代工業(yè)生產(chǎn)中,打包機作為產(chǎn)品包裝環(huán)節(jié)的關(guān)鍵設(shè)備,其穩(wěn)定運行和高效管理對于企業(yè)的生產(chǎn)效率和產(chǎn)品質(zhì)量至關(guān)重要。然而,傳統(tǒng)的打包機管理模式往往依賴人工巡檢和現(xiàn)場操作,存在數(shù)據(jù)采集不及時、設(shè)備狀態(tài)監(jiān)控
    的頭像 發(fā)表于 05-28 13:52 ?689次閱讀
    <b class='flag-5'>打包</b>機數(shù)據(jù)采集遠(yuǎn)程監(jiān)控系統(tǒng)方案

    Linux文件系統(tǒng)打包及鏡像制作,觸覺智能RK3562開發(fā)板演示

    本文介紹Linux開發(fā)板文件系統(tǒng)打包及鏡像制作的方法,演示Linux文件系統(tǒng)打包及鏡像制作,適用于想將配置好的系統(tǒng)環(huán)境打包成鏡像批量燒錄。觸
    的頭像 發(fā)表于 04-28 16:45 ?1136次閱讀
    <b class='flag-5'>Linux</b>文件系統(tǒng)<b class='flag-5'>打包</b>及鏡像制作,觸覺智能RK3562開發(fā)板演示
    淮安市| 石景山区| 赣榆县| 禹州市| 五大连池市| 桂阳县| 福安市| 基隆市| 蓬莱市| 北川| 莱阳市| 新竹市| 舞钢市| 九龙城区| 内黄县| 乃东县| 徐汇区| 绥宁县| 专栏| 洞口县| 华阴市| 肇源县| 临湘市| 庆城县| 衡水市| 大余县| 钟祥市| 兴义市| 昌黎县| 汝阳县| 天峻县| 乳源| 锡林浩特市| 上蔡县| 九龙县| 佛坪县| 同心县| 丰原市| 牙克石市| 新余市| 绩溪县|