tar在unix系統中是常被用來把許多檔案打包成一個檔案
和一般我們常見的壓縮檔(.zip .rar .7z)比較不同的就是
使用者可以選擇要用壓縮的方式或是不壓縮的方式來製作tar檔
下面wiki的網站有tar很詳細的介紹
http://en.wikipedia.org/wiki/Tar_file_format
這次作業是要寫出一個可以解讀一個tar檔裡所有資料的介紹
像是user id,group id 權限 檔名 檔案大小等
tar的sturct:
struct TarHeader {
char filename[100];
char filemode[8];
char userid[8];
char groupid[8];
char filesize[12];
char mtime[12];
char checksum[8];
char type[1];
char lname[100];
/* USTAR Section */
char USTAR_id[6];
char USTAR_ver[2];
char username[32];
char groupname[32];
char devmajor[8];
char devminor[8];
char prefix[155];
char pad[12];
struct TarHeader *next;// TarHeader *next;
//此行是自行加入 因要以link list的方式去做檔案的連接
};
執行範例:
$ ./mytar /student/test.tar
total 8 files
-rw-r--r-- root root 512 b9134001/512byte
drwxr-xr-x root wheel 0 b9134001/hw1/
-rw-r--r-- root wheel 256 b9134001/hw1/Makefile
-rw-r--r-- root wheel 551 b9134001/hw1/tarfile.h
-rw-r--r-- root wheel 318 b9134001/hw1/main.cpp
-rw-r--r-- root wheel 148 b9134001/hw1/main.h
-rw-r--r-- root wheel 1662 b9134001/hw1/tarfile.cpp
drwx------ b9134001 student 0 b9134001/hw3/
$ ./mytar mytar
Not a ustar file.
我把這次作業比較值得注意的部份筆記一下
1. seekg , read的使用
作業最常會使用的應該就是這兩個member fucntions
主要是分別控制我們讀進來資料流的位置及讀取範圍
* seekg(offset,postion)
ex:
inStream.seekg(0,ios::beg);
//資料流指標從InStream的開頭位置位移0個byte
*read(storage variable,offset)
ex:
inStream.read(ptr->filename,100);
//目前資料流指標往右位移100個byte的資料存入ptr->name
至於為什麼會常用到這兩個function呢?
因為我們可以從上面tar的struct看到
很多檔案資訊都是分散於資料流中不同的位置且佔不同大小
所以我們必須利用這兩個函式去存取我們真正需要的資料
2.各項目的轉換
知道了上面的用法後 我們就可以取出我們要的東西
其中"檔案權限" 、"檔案大小"的轉換是要特別注意的
一、檔案權限
檔案權限就是我們在linux下看到的 r w x
r:readable w:writable x:executable
然後又可分為
owner (此檔案擁有者的權限)
group (與此檔案擁有者同群組的權限)
other (其他不相干人的權限)
所以說 如果看到 rwx rwx rwx
(owner) (group) (other)
就表示任何在這台主機上的使用者
都能對此檔案做讀、寫、執行的動作
而tar檔中以0~7來表示權限
ex: rwx rwx rwx =777 (所有人都能讀寫執行)
r -- --- --x =401 (owner可讀 other可執行)
所以我們從tar檔取出權限的資料應該有三組0~7的數值
那要如何把這三組數字轉成我們要的rwx格式呢
我用的方式是把八種方式建表= =+
也就是
const string Mode[8]={"---","--x","-w-","-wx","r--","r-x","rw-","rwx"};
如果看到取到的資料是755 就直接分三次丟到table裡直接轉換
二、檔案大小
如果有看tar檔的介紹 應該知道為了要讓tar能讓不同系統都看得懂
他裡面的文字都是用ASCII來做編碼
而其中檔案大小又是以八進位來表示大小
比如說我們從tar檔取到檔案大小資料為221
那就是實際我們145byte
所以我還是建表.....= =+
const string OctToBin[8]={"000","001","010","011","100","101","110","111"};
首先先將讀到的資料減掉'0' 因為上面有提到說他是以ASCII做編碼
像'1' 他的int值就是 49 所以我們減掉'0'(int 48)取得int 1
把所得值丟進table 把轉換好的二進位數字串起來(strcat)
再用pow函式傳換成十進位
(助教: 這真是特別.....XD)
3.不同檔案間的連接
tar檔的內容排列示意圖為下:
我們可以從tar 的struct 算出他是以512byte為一個block
當檔案內容大於512時 他所占block就會增加
在讀下一個檔案時 資料流指標的位移就要多一個block
所以當我們要讀下一個檔案資訊時 就要依據上一個檔案大小
做我們資料流指標的位移
最後再用link list的方式把我們所有檔案資串起來
以計算此tar的檔案個數
4.其他
其他像user id groupid的東西
都只是透過1的方式去讀出 沒啥好講
--------------------------------------------------------------------
這次作業 我想除了是訓練對於資料流的操控外
還有就是文件拿到 怎麼透過文件的內容
去實做出功能的能力
還有就是建表的威力展現XD
- Apr 23 Wed 2008 15:21
[Object-Oriented Programming] HW2-mytar
close
全站熱搜
留言列表
發表留言