zlib庫編譯過程遇到的問題及其使用zlib庫進行解壓縮
目錄
1. 下載zlib
可以去官網http://www.zlib.net/ 下載zlib
2. 編譯zlib
ps:此處執行環境為VS2008+zlib1.2.7
step1:開啟VS2008的命令列執行視窗
step2:開啟命令列視窗後,進入zlib-1.2.7\contrib\masmx86目錄,輸入bld_ml32.bat命令,按下Enter鍵執行該命令
出現上述訊息說明編譯成功。
PS:由於現在機器基本都是64位,所以一般都是進入masmx64目錄,執行bld_ml64.bat。但由於我在Win7和Win10系統環境下執行時出現“ml64.exe不是內部或外部命令,也不是可執行的程式”錯誤,錯誤如下圖所示,由於作業系統內部會自動將32位軟體地址向64位地址對齊,因此在64位機器上使用32位軟體沒問題!綜上,我們這裡編譯bld_ml32.bat~
step3:進入目錄D:\zlib-1.2.7\contrib\vstudio\vc9,由於我使用的是vs2008執行,所以進入的是vc9目錄。接著用vs2008開啟zlibvc.sln
step4:vs2008開啟該檔案後,首先要將該專案屬性的前處理器設定為win32,然後編譯該專案(按一下F5~)
step5:此時D:\zlib-1.2.7\contrib\vstudio\vc9\x86目錄下就出現了一個ZlibDllDebug資料夾,裝有編譯好的dll庫和lib
以上zlib庫編譯完成~
3. 使用zlib庫解壓檔案
3.1 準備工作
要在專案中使用zlib庫解壓檔案,需要先做一些準備工作~在要使用zlib庫的專案檔案中新建一個資料夾,這裡我命名為zlib,裡面的檔案有:(由於這裡只是使用zlib庫解壓,所以包含以下檔案足以夠用)
此時還需要將zlibwapi.dll放到windows/System中,不然執行時會報錯~
最後只需在專案程式碼中加入這兩行程式碼即可~
#include "zlib/unzip.h"
#pragma comment(lib, "zlib/zlibwapi.lib")
以上準備工作完成,接下來可以在程式碼中使用zlib庫的函式對檔案進行解壓啦~
3.2 使用解壓函式對檔案進行解壓
1)開啟壓縮檔案。利用unzOpen64(char* filePath)函式開啟壓縮檔案,其返回值若為NULL則說明開啟壓縮檔案失敗;否則返回開啟unzFile型別的變數說明成功開啟壓縮檔案。
2)獲取壓縮檔案的全域性訊息。利用unzGetGlobalInfo64(unzFile zFile, unz_global_info64 *zGlobalInfo)函式獲取壓縮檔案的全域性訊息,放到unz_global_info64結構體中,其中有個重要的成員變數——壓縮檔案內所有檔案的數量,但不包括目錄。因此可以利用該函式得知壓縮檔案內的檔案數量。
3)迴圈遍歷壓縮檔案內的所有檔案,並將壓縮檔案解壓到本地檔案中(其實這就是將讀取到的檔案寫到本地檔案中,從而完成解壓)。
//遍歷所有檔案
unz_file_info64 zFileInfo;
unsigned int num = 512;
char *fileName = new char[num];
char *fileData = new char[500*1024];
// zGlobalInfo.number_entry就是獲取壓縮檔案的所有檔案數量
for(int i=0; i < zGlobalInfo.number_entry; i++)
{
// 獲得壓縮檔案裡的檔案(下稱為當前壓縮檔案)資訊(其中fileName是全路徑名)
if(UNZ_OK != unzGetCurrentFileInfo64(zFile,&zFileInfo,fileName,num,NULL,0,NULL,0))
{
cout<<"得到當前檔案資訊出錯"<<endl;
return ;
}
// 開啟當前壓縮檔案
if(UNZ_OK != unzOpenCurrentFile(zFile))
{
cout<<"開啟壓縮包中"<<fileName<<"檔案失敗"<<endl;
return ;
}
// 壓縮檔案全域性資訊結構體中的成員變數——未解壓前檔案的大小
int fileLength = zFileInfo.uncompressed_size;
//解壓縮檔案
// 讀取當前壓縮檔案,返回值為讀取的位元組長
int len;
len = unzReadCurrentFile(zFile,(voidp)fileData,fileLength);
fileData[len] = '\0';
//寫入到本地解壓縮後的檔案中
// 由於ofstream不能建立帶/的檔名,而fileName是絕對路徑,包括/,因此要先對fileName字串分割,獲得最後一個/後面的檔名,這才是我們所需要的解壓後檔名
std::string strFileName = fileName;
int nLength = strFileName.length();
int nPos ;
nPos = strFileName.find_last_of("/", nLength);
std::string strPath = strFileName.substr(nPos+1, nLength);
std::ofstream file(strPath.c_str(),std::ios::out|std::ios::binary);
if(!file.good())
{
cout<<"file not good"<<endl;
return ;
}
// 將指標定位到檔案的一開始
file.seekp(0,std::ios::beg);
file.write(fileData,len);
file.close();
// 關閉當前解壓檔案
unzCloseCurrentFile(zFile);
// 下一個解壓檔案
unzGoToNextFile(zFile);
}
unzClose(zFile);
delete[] fileData;
完整解壓程式碼如下:
void unzip(LPCTSTR szSavePath)
{
unzFile zFile;
// Unicode轉為ANSI
char filePath[MAX_PATH];
WideCharToMultiByte(CP_ACP, 0, szSavePath, -1, filePath, MAX_PATH, NULL, NULL);
// 開啟壓縮檔案
zFile = unzOpen64(filePath);
if (zFile == NULL)
{
//MessageBox(L"開啟壓縮檔案失敗");
return;
}
// 獲取壓縮檔案的全域性訊息
unz_global_info64 zGlobalInfo;
// 重要成員變數是壓縮檔案內所有檔案的數量(不包括目錄)
if (UNZ_OK != unzGetGlobalInfo64(zFile, &zGlobalInfo))
{
//OutputDebugString(__FILE__ + L"中"+__LINE__+L"行錯誤,得到全域性資訊出錯");
return;
}
// 迴圈遍歷所有檔案
unz_file_info64 zFileInfo;
unsigned int num = 512;
char *fileName = new char[num];
char *fileData = new char[500*1024];
for(int i=0; i < zGlobalInfo.number_entry; i++)
{
//遍歷所有檔案(fileName是全路徑名)
if(UNZ_OK != unzGetCurrentFileInfo64(zFile,&zFileInfo,fileName,num,NULL,0,NULL,0))
{
//cout<<"得到當前檔案資訊出錯"<<endl;
return ;
}
if(UNZ_OK != unzOpenCurrentFile(zFile))
{
//cout<<"開啟壓縮包中"<<fileName<<"檔案失敗"<<endl;
return ;
}
int fileLength = zFileInfo.uncompressed_size;
int len;
//解壓縮檔案
len = unzReadCurrentFile(zFile,(voidp)fileData,fileLength);
fileData[len] = '\0';
//寫入到解壓縮後的檔案中
std::string strFileName = fileName;
int nLength = strFileName.length();
int nPos ;
nPos = strFileName.find_last_of("/", nLength);
std::string strPath = strFileName.substr(nPos+1, nLength);
std::ofstream file(strPath.c_str(),std::ios::out|std::ios::binary);
if(!file.good())
{
//cout<<"file not good"<<endl;
return ;
}
file.seekp(0,std::ios::beg);
file.write(fileData,len);
file.close();
unzCloseCurrentFile(zFile);
unzGoToNextFile(zFile);
}
unzClose(zFile);
delete[] fileData;
}
相關文章
- 使用zlib庫解壓zip檔案
- 編譯和使用zlib編譯
- C/C++ Zlib庫封裝MyZip壓縮類C++封裝
- mingw下編譯zlib quazip動態庫編譯
- 淺談在c#中使用Zlib壓縮與解壓的方法C#
- Android 編譯 zlibAndroid編譯
- Swoole WebSoctet 使用 zlib 壓縮之 PHP 與 pako.jsWebPHPJS
- Python模組學習:zlib 資料壓縮Python
- Android Java壓縮Zlib,Gzip,Zip支援J2MEAndroidJava
- Linux安裝boost、libevent、zlib、OpenSSL庫Linux
- 不使用dbca進行手工建庫的過程
- 重新編譯hadoop-2.7.2-src的native以支援Snappy解壓壓縮庫編譯HadoopAPP
- Ubuntu16.04編譯VIORB過程中遇到的問題 尤其是rosbag的問題Ubuntu編譯ORBROS
- linux下給php安裝pdo_mysql和zlib以及測試模式的選擇(禪道安裝過程中遇到的問題)LinuxPHPMySql模式
- 交叉編譯庫依賴問題的解決方法編譯
- 使用阿里雲的Maven倉庫加速Spark編譯過程阿里MavenSpark編譯
- Latex — 寫作編譯過程中遇到問題記錄與總結編譯
- 問題解決zipimport.ZipImportError: can‘t decompress data; zlib not availablImportErrorAI
- Linux使用過程中常見問題及其解決方法Linux
- [nghttp2]壓測工具,原始碼編譯並進行deb打包過程HTTP原始碼編譯
- CMake構建學習筆記2-zlib庫的構建筆記
- dos下編譯執行java程式遇到的問題編譯Java
- 編譯安裝pcre2-10.39 zlib-1.3.1 openssl-3.0.13編譯
- aix5.3 + oracle9206 建庫過程中遇到的問題及解決AIOracle
- 《從零開始搭建遊戲伺服器》 網路資料壓縮——Zlib演算法遊戲伺服器演算法
- 【Java】程式設計過程中遇到的中文編碼問題Java程式設計
- 使用RMAN duplicate對源庫的某個incarnation進行duplicate操作時遇到的問題
- vscode 自定義c++標頭檔案,編譯過程中遇到的問題VSCodeC++編譯
- 爬蟲過程中遇到的問題爬蟲
- Composer 使用過程中遇到的問題和解決方案
- Mac電腦使用imazing過程中遇到的問題Mac
- ORACLE 資料庫分析,重新編譯失敗過程Oracle資料庫編譯
- 使用flask的時候遇到的問題及其解答Flask
- ubuntu下安裝nginx時依賴庫zlib,pcre,openssl安裝方法UbuntuNginx
- 使用Java API進行tar.gz檔案及資料夾壓縮解壓縮JavaAPI
- 清理微控制器編譯過程中產生的編譯檔案(壓縮以減少專案體積)編譯
- C# 關於壓縮、加密、解壓問題C#加密
- 學習vue過程中遇到的問題Vue