1. 程式人生 > >使用minizip解壓縮多個檔案(基於zlib)

使用minizip解壓縮多個檔案(基於zlib)

寫作目的:之前在網上看到很多人在尋找可以解壓縮多個檔案的程式,其中有嘗試zlib的,使用zlib的原始碼可以生成字尾為點gz的壓縮檔案,但是一次只能壓縮一個檔案,無法壓縮多個檔案。其實,zlib的原始碼包裡有一個第三方的contrib已經實現解壓縮多個檔案,這就是minizip。下面就來看看是怎麼操作的。

下載zlib原始碼

去zlib網站下載原始碼並解壓,
這裡寫圖片描述
這裡選擇tar.gz格式的原始碼包下載(其它格式都可以)
這裡寫圖片描述

編譯zlib

進入到zlib-1.2.11目錄下,發現有個Makefile檔案,開啟如下,
這裡寫圖片描述
這是個提示,讓我們先執行./configure。按照提示我們在終端輸入./configure並回車,執行完畢後再開啟看Makefile,發現裡面就有內容了,
這裡寫圖片描述


此時在終端輸入make,這樣zlib原始碼就開始編譯了。
編譯完畢後如果輸入make install,就可以把編譯好的zlib庫放在系統路徑裡,以後寫程式碼就可以直接呼叫zlib提供的庫函數了。
以上這些操作資訊是寫在原始碼目錄下的readme檔案裡的,這裡擷取一段,
這裡寫圖片描述
還有講example的,告訴我們example原始碼在哪,
這裡寫圖片描述
原始碼目錄下還有個INDEX檔案,裡面敘述了構成zlib的所有public header files和private source files,有了這些資訊,就可以很方便的把需要的原始碼整合到自己的工程中去。
這裡寫圖片描述
可以看出作者的文件寫的非常好。

minizip

下面就來解決之前說的問題:解壓縮多個檔案(基於minizip)。
minizip原始碼目錄在zlib-1.2.11/contrib目錄下,進入這個目錄,先看下該目錄下的README.contrib檔案,這個檔案描述了基於zlib寫的的第三方contributions,找到minizip的,
這裡寫圖片描述
似乎得不到啥有用的資訊,我們直接進入minizip的目錄,
這裡寫圖片描述
有個Makefile,開啟如下,
這裡寫圖片描述
內容比較簡單,就是編譯出2個elf檔案:miniunz和minizip。通過名字就可以知道一個是用來解壓,另一個用來壓縮。
其中,

  • 生成miniunz需要用到miniunz.c,unzip.c,ioapi.c和之前編譯zlib時生成的靜態庫libz.a
  • 生成minizip需要用到minizip.c,zip.c,ioapi.c和之前編譯zlib時生成的靜態庫libz.a

輸入make執行Makefile,會有幾個warning,
這裡寫圖片描述
定位到miniunz.c的100行,
這裡寫圖片描述
這種條件編譯寫法是比較老的,現在編譯器已經不提倡這種寫法了,所以改為如下,
這裡寫圖片描述
再編譯就沒這個warning了,按照這種方法也可以消除minizip.c中97行的warning。最後還剩個mkdir未宣告,一般這是因為沒有對應的標頭檔案導致的,在終端輸入man 2 mkdir並回車,
這裡寫圖片描述
可以看出mkdir對應的是2個頭檔案,把這2個頭檔案新增到miniunz.c裡,再次編譯,就沒有任何warning了。

編譯完成後,就可以在minizip目錄下看到2個elf檔案:miniunz和minizip。這裡先測試一下minizip,在終端輸入./minizip -h並回車,得到以下幫助資訊,
這裡寫圖片描述
我們在minizip目錄下新建一個目錄test,然後把minizip拷貝進去,然後在test目錄下建2個檔案a.txt和b.txt,隨意寫點內容在裡面。
這裡寫圖片描述
然後按照之前的幫助資訊,輸入./minizip -o -9 target.zip a.txt b.txt 並回車,可以發現生成了target.zip檔案,開啟它發現實現了多個檔案的壓縮,
這裡寫圖片描述
這裡寫圖片描述
再來測試下miniunz,先把a.txt和b.txt刪除,再把miniunz拷貝進來。先看下miniunz的幫助資訊,輸入./miniunz -h並回車,結果居然有error,說明這個miniunz.c裡的main函式寫的不夠好,沒有對-h的支援,畢竟是第三方contributions
這裡寫圖片描述
不過沒關係,一般來說-h不行,那麼就直接./miniunz回車,這次幫助資訊出來了,
這裡寫圖片描述
我們輸入./miniunz -x target.zip,提示解壓成功,我們看下目錄,確實OK了。
這裡寫圖片描述

加密解壓縮

解壓縮多個檔案已經測試OK,下面就來測試以下加密解壓縮多個檔案,畢竟minizip和miniunz的幫助資訊裡顯示是支援加密的。
先測試minizip的加密功能,終端下輸入./minizip -o -9 -p 123 target_crypt.zip 1.txt 2.txt並回車,可以看到生成了target_crypt.zip檔案,雙擊開啟它,提示需要輸入密碼,
這裡寫圖片描述
我們輸入123,發現可以正確開啟,說明加密功能沒問題。

下面測試一下miniunz的解密功能(先把a.txt和b.txt刪除),終端輸入./miniunz -x -p 123 targer_crypt.zip並回車,發現竟然無法解密,
這裡寫圖片描述
根據提示,是unzOpenCurrentFilePassword()函式返回了-102,我們去找一下unzOpenCurrentFilePassword()的定義,回到minizip目錄下使用grep去查詢,
這裡寫圖片描述
發現該函式定義在unzip.c裡,開啟unzip.c找到這個函式,
這裡寫圖片描述
函式開始處就有個可能返回的值UNZ_PARAMERROR,再用grep查下這個巨集定義,
這裡寫圖片描述
發現這個值就是-102,看來函式執行到這個return語句了。再看下程式碼,可以推斷出NOUNCRYPT被定義了,而這個巨集從字面感覺是沒有密碼的意思,難道miniunz的工程遮蔽瞭解密功能?我們再用grep查下NOUNCRYPT,看下在哪裡設定的,
這裡寫圖片描述
可以看出是在unzip.c裡定義的巨集,進去檢視下,
這裡寫圖片描述
果然是定義了NOUNCRYPT,把解密功能遮蔽了。既然找到了問題的根源,那麼解密失敗的問題就迎刃而解了:把這三行語句遮蔽掉,然後重新編譯,重新生成miniunz,並拷貝到test目錄下。再次輸入./miniunz -x -p 123 target_crypt.zip並回車,就可以了。

看來這個miniunz還是有點小bug的,不過仔細研究下也很容易解決。

總結

minizip可以達到解壓縮多個檔案的要求,而且其原始碼也比較少,結構也簡單清晰,可以很方便地整合到自己的工程中來,或者自己修改,這就需要自己去研究下原始碼了。
如果想偷懶的話,可以只看minizip.c和miniunz.c裡的main函式,把它改成一個介面函式,來達到自己的需求。

如果有寫的不對的地方,希望能留言指正,謝謝閱讀。

相關推薦

使用minizip壓縮檔案基於zlib

寫作目的:之前在網上看到很多人在尋找可以解壓縮多個檔案的程式,其中有嘗試zlib的,使用zlib的原始碼可以生成字尾為點gz的壓縮檔案,但是一次只能壓縮一個檔案,無法壓縮多個檔案。其實,zlib的原始碼包裡有一個第三方的contrib已經實現解壓縮多個檔案,這就

input型別上傳檔案selenium+Python

一般上傳方法分為兩種:input型別和非input型別,這裡具體分析input型別。 html檔案: 【上傳圖示】按鈕元素定位中包含name=“file”   type="file"  果斷採用input+sendkeys模式。 一、上傳一張圖片,上程式碼: 解釋

ZIP——記憶體壓縮檔案

using ICSharpCode.SharpZipLib.Zip; namespace MindExportLearning.Util { /// <summary> /// 壓縮和解壓檔案 /// </summary>

Linux下如何編譯有檔案包括不同目錄下的.c/.h檔案的C/C++程式

在Linux下要編譯一個C/C++程式,首先要知道包含目錄的作用,對C/C++有了解的就會知道,#include是包含標頭檔案所用的,也就說說部分類、函式、或者變數宣告就在其中。而#include巨集定義又有兩種: #include""和#include <>

tomcat中專案web專案共用log4j.jar的情況下,如何讓其各自列印各自的日誌檔案。及輸出同級別日誌資訊

問題描述: 1.專案A中有一個log4j.properties(配置為把日誌輸出到以專案名稱命名的資料夾中)  2.為了減輕tomcat負擔,把專案A的WEB-INF/lib下的所有jar檔案拷貝到tomcat下的lib中並修改catalina.properties對其載入

如何壓縮檔案/資料夾(GZipStream and C#)

publicclass GZip     {         ///<summary>/// Compress         ///</summary>///<param name="lpSourceFolder">The location of the f

在一臺Apache服務器上創建站點不同域名

admin 進程 HR 開啟 ron serve vhost web 解析 使用不同的域名來區分不同的網站,所有的域名解析都指向同一個 IP 地址。Apache通過在HTTP頭中附帶的 host參數來判斷用戶需要訪問哪一個網站。 例如要在一臺服務器上設置如下兩個

執行TomcatWindows平臺

需求:在一臺計算機上,只安裝一份Tomcat發行版軟體,執行一個以上的Tomcat例項。 或者,因為計劃週期性地更新所安裝的Tomcat,不想把Web應用程式的檔案放入Tomcat發行版的目錄樹中。   解決方案: 《Tomcat權威指南》第2章重置Tomcat,重定向We

SpringSecurity配置HttpSecuritySpringBoot適用

package pers.lbw.digitalmall.config; import org.springframework.context.annotation.Configuration; import org.springframework.core.annotation.Orde

linux下搭建svn添加倉庫項目

con 加權 linu 刪除 密碼 etc none tar cep 1): 創建svn版本庫路徑 mkdir -p /opt/svn/project1 mkdir -p /opt/svn/project2 ...

Pandas 合併Dataframemerge,concat

在資料處理的時候,尤其在搞大資料競賽的時候經常會遇到一個問題就是,多個表單的合併問題,比如一個表單有user_id和age這兩個欄位,另一個表單有user_id和sex這兩個欄位,要把這兩個表合併成只有user_id、age、sex三個欄位的表怎麼辦的,普通的拼接是做不到的

intellij idea在project下同時開啟工程maven工程

前提:我的工程都是maven工程   我有兩個工程,一個是介面contract,一個是介面的具體實現server。想要同時在一個工作空間下展示,方便除錯開發,載入後效果如下   idea有workspace的概念,即工作空間。支援多個工程在一個

oracle將一個欄位拆分成regexp_substr函式

例: select regexp_substr(p.attributename, '[^,]+',1,level) c1 from tablename p connect by level &l

單因子 & 因子策略基於JoinQuant

## step1:匯入所需的庫import pandas as pdfrom pandas import Series, DataFrameimport numpy as npimport statsmodels.api as smimport scipy.stats as scsimport matplo

Netty ServerBootstrap 繫結程式碼示例

EventLoopGroup bossGroup = new NioEventLoopGroup(); EventLoopGroup workerGroup = new NioEventLoopGroup(); try { ServerBoot

使用zlib壓.apk/.zip檔案Windows&Ubuntu

前言 前面講過,解壓出apk檔案的內容是進行apk分析的第一步,而.apk檔案其實就是.zip檔案。也就是說首先要實現zip檔案的解壓縮。本文將分別介紹在Windows和Ubuntu下如何使用zlib這一開源庫對zip檔案進行解壓。 Git Z

在ASP.NET MVC 模型中 選擇最好的方法將model資料模型傳遞到檢視

無論你什麼時候需要保持一些資訊直到一個接著的後來的請求,使用TempData都是很好的方法。它應該在你需要保持例如驗證資訊,錯誤資訊,或者一些小的不包含敏感資料資訊的時候使用。因為它能保證會話來傳遞變數,所以你不應該把敏感的資訊存放在TempData。 (adsbygoogle =

activiti 如何設定審批人十五

1、activiti 中有互斥閘道器 和 並行閘道器;在實際專案開發中,經常會出現一項功能,任意審批人審批都可以的情況; 例如:在5院委外專案申請中,生產單位上報的申請,計劃經營處中任意一人審批,該申

用C語言程式設計實現建立目錄資料夾

    因為要建立90個資料夾,本人實在不想一個一個的建立,就想是不是可以用C語言程式設計來實現呢,剛才查閱了很多部落格,終於終於我實現了,可以用迴圈的方式建立了,也不屬於自己原創,參考了很多大神的程式碼。現在我把原始碼貼出來,在Visual studio 2015上跑成功了

在C#中建立、讀、寫EXCEL檔案基於COM

1. EXCEL Library 在使用C#中的excel模組之前,我們需要先把excel library加入到project中。 首先建立一個空專案,然後建立一個按鈕。隨後,如下圖點選“專案”->“新增引用”: 隨後選擇microsoft excel 1X.0 o