windows下解壓tar.gz檔案

來源:互聯網
上載者:User

標籤:標識   .dll   命令列   www.   manual   文章   war   com   資料   

最近做的一個項目,使用小工具代替人工提交到網站並擷取結果。

在開發過程中碰到了一個問題。

網站返回的格式為tar.gz檔案。第一個想到的方式是直接用第三方工具,使用的是7z。但使用者那裡使用的系統為win10,不以管理員身份運行會沒有調用第三方工具的許可權。遂決定用庫解決該問題。

這裡記錄下windows下解壓tar.gz的一些問題。

其實tar.gz是兩次封裝。

第一次是tar打包(這裡不會壓縮,檔案反而會更大),第二次是gz檔案的演算法壓縮。

解壓GZ檔案使用的是zlib庫。

這裡說一下zlib的使用過程。

一開始我是圖懶直接從官網下載的windows develop版本,包含標頭檔,靜態庫和dll。但運行過程中出現了缺少zlib1.dll的問題。經過反覆的折騰,沒有解決。他這個庫產生時間是2005年,可能在新版windows下運行會有問題把。

本人對系統瞭解還是不多,沒有找到深層次的原因。如果有大神知道原理請告知。

在此之後下載了新版並進行編譯。具體編譯過程忘記了,挺順利的。在vs命令列裡執行一條命令後,會直接產生vs工程項目。選擇靜態庫或動態庫編譯即可。

不知道這裡能不能發csdn的串連,我是根據這篇文章來編譯的:http://blog.csdn.net/shellching/article/details/8116622。

當然我用的版本是vs2015。用這種方法也能順利通過。

接下來就是解壓了。一開始我從網上找到的資料全是compress和uncompress,後來發現:

錯啦!

壓根就不是這麼解壓的。

具體原因沒有詳細瞭解到,大體上我的理解就是,其實gz檔案需要一個頭來標識壓縮層級等資訊。而compress和uncompress只是壓縮位元組流,單純地調用uncompress而不知道資料的開始位置和資料的壓縮資訊的話,是無法正常壓縮的。

下面是解壓代碼:


//初始化結構體

z_stream strm = { 0 };

strm.zalloc = Z_NULL;

strm.zfree = Z_NULL;
strm.opaque = Z_NULL;


 

//下面分別初始化來源資料,來源資料長度,目標資料長度和目標資料地址

strm.next_in = srcBuffer;
strm.avail_in = srcLength;
strm.avail_out = dstLength;
strm.next_out = dstBuffer;

//下面函數的第二個參數在標頭檔的函數說明裡有,這裡的這個參數意思是自動判斷資訊頭
int res = inflateInit2(&strm, MAX_WBITS + 32);

//執行解壓縮

res = inflate(&strm, Z_NO_FLUSH);

//回收資源
inflateEnd(&strm);

上面的代碼我去掉了結果判斷的部分,具體的結果判斷大家參考標頭檔的資訊把。我其實在代碼裡沒有進行詳細判斷,只是簡單判斷了成功失敗,並沒有返回原因。這裡就不貼上來坑大家了。

有幾點注意事項:

1,目標記憶體長度需要足夠。當然不夠也沒關係,該函數會在執行時發現並返回這個錯誤,在判斷後逐步增加緩衝區即可。

2,轉換成功後目標資料的長度為:dstLen - strm.avail_out。

3,如果你編譯後使用這些函數,這個程式會莫名其妙地崩掉。

4,如果你是新手(現在沒啥新手在VS上用這個了把。。。),可能會報無法串連的錯誤,當然你引入了lib還是會報。

 

先說下為何會報串連錯誤,需要加一個宏ZLIB_WINAPI,如果有新手在看的話,跟大家分享下。

一個庫,無論是靜態還是動態。在有標頭檔的時候,有兩個地方需要注意,一是你編譯庫的時候,匯出函數前面有沒有加export,第二個是你引入庫的時候,匯出函數前面是不是import。

有些庫因為要處理跨平台的問題,庫的源碼的宏定義會非常複雜,這時候要仔細觀察,設定響應的宏確定庫函數的正確引入和匯出,如果你用VS的話,VS會根據宏定義的狀態來高亮具體代碼用到哪個宏。

在編譯和引入的時候都要注意。

 

接下來,在崩潰之後,各種google原因,但始終沒有發現是為什麼,因為當時沒有解壓成功,我也一度懷疑自己的代碼有問題,或者庫有問題。

在這裡,感謝一位大神:http://blog.csdn.net/u013283835/article/details/70311499

真是跪謝。這是怎麼發現的。祝您能修到孫藝珍。

根據這位大神的說法,把前置處理器中的ASMINF這個宏去掉。執行程式將轉換出來的位元組流寫入檔案。搞定了。

這裡鄙視下CSDN:本人的csdn因為前幾年給別人發QSS代碼被封了。我也是醉了,發個QSS代碼都能封。就這還搞技術論壇。呵呵。

 

接下來就進行tar檔案的解析了。最開始想到的使用libarchive庫。

嗯。編譯,串連,匯入,使用。在經曆過種種挫折後,我突然發現:libarchive不支援全路徑,只能開啟當前工作目錄下的檔案,當然也可能是我某個配置沒有配好,但libarchive的資料實在是太少了。

官方文檔也只有很粗略的解釋。而且在win10下,如果程式安裝在C盤program files下,運行程式是沒有建立檔案許可權的,在其他盤則需要不停設定當前路徑。放棄。這個庫真不是一般的難用。

查了下tar檔案的格式:

http://blog.chinaunix.net/uid-20357359-id-1963469.html

https://www.gnu.org/software/tar/manual/html_node/Standard.html

嗯,貌似做簡單的拆包不複雜嗎。外加我做的小項目中tar檔案本就是自動產生的,只有一級目錄。自己解決把。

下面是代碼:

 

typedef struct posix_header

{
char name[100];
char mode[8];
char uid[8];
char gid[8];
char size[12];
char mtime[12];
char chksum[8];
char typeflag;
char linkname[100];
char magic[6];
char version[2];
char uname[32];
char gname[32];
char devmajor[8];
char devminor[8];
char prefix[155];
}TAR_HEADER;

//參數為目標路徑、tar緩衝區,緩衝區長度
void ExtractTar(const char *dstDir, BYTE *buffer, uLongf len){ uLongf index = 0; while (true) { if (index == len - 1) { return; } TAR_HEADER newHeader = { 0 }; memcpy(&newHeader, buffer + index, sizeof(TAR_HEADER)); index += sizeof(TAR_HEADER); if (strcmp(newHeader.name, "") == 0) { return; } char fileFullPath[MAX_PATH] = { 0 }; memcpy(fileFullPath, dstDir, strlen(dstDir)); memcpy(fileFullPath + strlen(dstDir), newHeader.name, strlen(newHeader.name)); FILE *newFile = NULL;     fopen_s(&newFile, fileFullPath, "wb+");long size = strtol(newHeader.size, (char **)(&(newHeader.size) + 12), 8); size_t res = fwrite(buffer + index, 1, size, newFile); fclose(newFile); index += size;

     //填充位元組塊 int nblock = index / 512 + 1; index = nblock * 512; }}

注意:

1,我還是去掉了返回判斷的代碼,如果想完成健壯代碼請判斷各種狀態傳回值。

2,這段代碼不能解壓包含檔案夾或者多級目錄的tar檔案,也不能解壓特殊檔案,也沒有判斷位元組位移等資料。

簡單來說,這段代碼只能保證我這個小項目的需求。而且很大程度上滿足不了其他需求。

 

經過上面兩步,基本上滿足了我的需求。在這裡分享給大家。

 

windows下解壓tar.gz檔案

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.