Linux下使用zlib實現資料壓縮解壓
1、背景
本文舉例說明了:專案過程中字串資料傳輸的場景下(檔名列表),如何使用資料壓縮減少頻寬的開銷;
2、相關知識
引用外部的一個手冊進行說明
3、實現方法
deflate壓縮實現,壓縮完成後會提示Z_STREAM_END
int gzcompress(void *data, size_t ndata, void *zdata, size_t *nzdata) { int ret = -1; z_stream c_stream; if (!data || !ndata) { printf("NULL\n"); return -1; } c_stream.zalloc = NULL; c_stream.zfree = NULL; c_stream.opaque = NULL; if (deflateInit2(&c_stream, Z_DEFAULT_COMPRESSION, Z_DEFLATED, MAX_WBITS + 16, 8, Z_DEFAULT_STRATEGY) != Z_OK) { printf("deflateInit2\n"); return -1; } c_stream.next_in = (Bytef *)data; c_stream.avail_in = ndata; c_stream.next_out = (Bytef *)zdata; c_stream.avail_out = *nzdata; while (c_stream.avail_in != 0 && c_stream.total_out < *nzdata) { if (deflate(&c_stream, Z_NO_FLUSH) != Z_OK) { printf("deflate\n"); goto end; } } if (c_stream.avail_in != 0) { printf("%d\n", c_stream.avail_in); return c_stream.avail_in; } for (;;) { ret = deflate(&c_stream, Z_FINISH); if (ret == Z_STREAM_END) { printf("deflate: Z_STREAM_END\n"); break; } else if (ret != Z_OK) { printf("deflate: %d\n", ret); break; } } end: if (deflateEnd(&c_stream) != Z_OK) { printf("deflateEnd: Failure\n"); return -1; } *nzdata = c_stream.total_out; return 0; }
inflate解壓實現,注意解壓完成是返回Z_STREAM_END,遇到Z_OK需要繼續處理
int gzdecompress(void *zdata, size_t nzdata, void *data, size_t *ndata) { int ret = -1; z_stream d_stream = {0}; /* decompression stream */ static char dummy_head[2] = { 0x8 + 0x7 * 0x10, (((0x8 + 0x7 * 0x10) * 0x100 + 30) / 31 * 31) & 0xFF, }; d_stream.zalloc = NULL; d_stream.zfree = NULL; d_stream.opaque = NULL; d_stream.next_in = (Bytef *)zdata; d_stream.avail_in = 0; d_stream.next_out = (Bytef *)data; if (inflateInit2(&d_stream, MAX_WBITS + 16) != Z_OK) { printf("inflateInit2\n"); return -1; } while (d_stream.total_out < *ndata && d_stream.total_in < nzdata) { d_stream.avail_in = d_stream.avail_out = 1; /* force small buffers */ ret = inflate(&d_stream, Z_NO_FLUSH); switch (ret) { case Z_OK: continue; case Z_STREAM_END: printf("inflate: Z_STREAM_END\n"); goto end; case Z_DATA_ERROR: d_stream.next_in = (Bytef *)dummy_head; d_stream.avail_in = sizeof(dummy_head); if ((ret = inflate(&d_stream, Z_NO_FLUSH)) != Z_OK) { printf("inflate failed\n"); goto end; } break; default: printf("inflate: %d\n", ret); goto end; } } end: if (inflateEnd(&d_stream) != Z_OK) { printf("inflateEnd: Failure\n"); return -1; } *ndata = d_stream.total_out; return 0; }
測試函式如下,使用了檔案列表進行測試:
int main(int argc, char *argv[]) { int ret = -1; char input[] = ( "/usr/local/vim\n" "/usr/local/vim/share\n" "/usr/local/vim/share/vim\n" "/usr/local/vim/share/vim/print\n" "/usr/local/vim/share/vim/keymap\n" "/usr/local/vim/share/vim/autoload\n" "/usr/local/vim/share/vim/autoload/xml\n" "/usr/local/vim/share/vim/indent\n" "/usr/local/vim/share/vim/macros\n" "/usr/local/vim/share/vim/mang/sk\n" "/usr/local/vim/share/vim/lang/sk/LC_MESSAGES\n" ); char gzip[1024] = {0}; char output[1024] = {0}; size_t ngzip = sizeof(gzip); size_t nout = sizeof(output); assert((ret = gzcompress(input, sizeof(input), gzip, &ngzip)) == 0); assert((ret = gzdecompress(gzip, ngzip, output, &nout)) == 0); printf(" input: %zd\n%s\n", sizeof(input), input); printf("output: %zd\n%s\n", nout, output); printf("Result:\t\t\t\t[%s]\n", ret ? "Failure" : "Success"); exit(ret ? EXIT_FAILURE : EXIT_SUCCESS); }
執行結果如下:
deflate: Z_STREAM_END
inflate: Z_STREAM_END
input: 339
/usr/local/vim
/usr/local/vim/share
/usr/local/vim/share/vim
/usr/local/vim/share/vim/print
/usr/local/vim/share/vim/keymap
/usr/local/vim/share/vim/autoload
/usr/local/vim/share/vim/autoload/xml
/usr/local/vim/share/vim/indent
/usr/local/vim/share/vim/macros
/usr/local/vim/share/vim/mang/sk
/usr/local/vim/share/vim/lang/sk/LC_MESSAGES
output: 339
/usr/local/vim
/usr/local/vim/share
/usr/local/vim/share/vim
/usr/local/vim/share/vim/print
/usr/local/vim/share/vim/keymap
/usr/local/vim/share/vim/autoload
/usr/local/vim/share/vim/autoload/xml
/usr/local/vim/share/vim/indent
/usr/local/vim/share/vim/macros
/usr/local/vim/share/vim/mang/sk
/usr/local/vim/share/vim/lang/sk/LC_MESSAGES
Result: [Success]
4、結論
deflate(RFC1951):一種壓縮演算法,使用LZ77和哈弗曼進行編碼;
zlib(RFC1950):一種格式,是對deflate進行了簡單的封裝,他也是一個實現庫(delphi中有zlib,zlibex)
gzip(RFC1952):一種格式,也是對deflate進行的封裝。
gzip = gzip頭 + deflate編碼的實際內容 + gzip尾
zlib = zlib頭 + deflate編碼的實際內容 + zlib尾
以上例子通過一次性將字串資料壓縮轉換成資料流形式,在工程中實踐的意義就是犧牲CPU計算換取頻寬的方法;
相關推薦
Linux下使用zlib實現資料壓縮解壓
1、背景 本文舉例說明了:專案過程中字串資料傳輸的場景下(檔名列表),如何使用資料壓縮減少頻寬的開銷; 2、相關知識 引用外部的一個手冊進行說明 3、實現方法 deflate壓縮實現,壓縮完成後會提示Z_STREAM_END int gzcompress(void *d
linux下安裝配置jdk(解壓版)
生效 測試 linu 文件 info img url www 技術 在linux下登錄oracle官網,下載解壓版jdk 傳送門 系統默認下載到“下載”目錄中 創建要將該文件解壓的文件夾: 其中 -p 參數代表遞歸創建文件夾(可以創建多級目錄) 進
Linux下 解決Tomcat8不自動解壓war包
之前買了阿里雲伺服器後配置好了jdk,Tomcat,mysql等。然後就想當然的將專案打成war包,直接拖到Tomcat的webapps下,但無論怎麼重啟專案就是不自動解壓,後來查了各方面資料,刪除這個檔案那個檔案的,差點把Tomcat搞崩潰了也沒找到原因,最後看到講一個將Tomcat裡
linux下Oracle實現資料的自動備份
由於近期工作的原因,要做一個簡單的oracle資料自動備份,因為是一個單體應用,所以就利用了linux的定時任務和oracle的exp進行資料備份,如果有不足和需要改正的地方,歡迎各位高手指正,不勝感
Linux中使用gzip來壓縮/解壓 *.gz檔案
gzip 是linux中常見的壓縮/解壓工具,最常見的使用物件是*.gz格式的檔案,這裡簡單介紹下它最常見的用法, GZIP(1) General Commands Manual GZIP(1)NAME gzip, gunzip, zcat - compress
unity ZIP壓縮解壓 Byte[]資料壓縮解壓
在網上看了一些相關資源,都比較散;為了方便以後檢視,我就整理一下 記性比較差長時間不接觸說不定就忘了 我這給一個ICSharpCode.SharpZipLib的下載連結:https://pan.baidu.com/s/1o8QcYkq 朋友們也可以百度找最新的下載一個就行
GZIP資料壓縮/解壓工具
GZIP概念 GZIP最早由Jean-loup Gailly和Mark Adler建立,用於UNⅨ系統的檔案壓縮。我們在Linux中經常會用到字尾為.gz的檔案,它們就是GZIP格式的。現今已經成為Internet 上使用非常普遍的一種資料壓縮格式,或者說一種
linux下基本操作指令,解壓,刪除檔案操作
一般首先是安裝vmtools之後,就可以實現linux虛擬機器和主機windows的檔案的直接拖拽,這樣就會比較方便windows和linux的互動。 在指導學生做CSAPP課程實驗時,發現好多學生對基本的linux下檔案操作不能掌握,導致實驗無法順利開展,最重要的就是li
linux下下載的zip檔案解壓之後中文檔名亂碼
我在下載一些檔案的時候,我的ubunt 14.04預設按照zip檔案給我打包下載的,但是下載下來之後,發現解壓之後我的中文檔名先試試的都為亂碼,後來看了其他部落格博主的一些解決方法,發現這麼一個好的方法,親試OK的。 第一步 首先安裝7zip和convmv(如
C#實現Zip壓縮解壓實例
bsp dll entry static empty reat lec pac 壓縮 本文只列舉一個壓縮幫助類,使用的是有要添加一個dll引用ICSharpCode.SharpZipLib.dll【下載地址】。 另外說明一下的是,這個類壓縮格式是ZIP的,所以文件的後綴寫
Linux下解包/打包,壓縮/解壓命令
res file bzip2 lena dirname unzip bz2 裏的 dir .tar 解包:tar xvf FileName.tar 打包:tar cvf fileName.tar DirName tar.gz和.tgz 解壓:tar zxvf FileNam
Linux下常用壓縮解壓命令
tar 解包:tar xvf FileName.tar 打包:tar cvf FileName.tar DirName (注:tar是打包,不是壓縮!) .gz 解壓1:gunzip FileName.gz 解壓2:g
Linux下常用壓縮 解壓命令和壓縮比率對比
常用的格式有: tar, tar.gz(tgz), tar.bz2, 不同方式,壓縮和解壓方式所耗CPU時間和壓縮比率也差異也比較大。 tar 只是打包動作,相當於歸檔處理,不做壓縮;解壓也一樣,只是把歸檔檔案釋放出來。 (1)打包歸檔格式: tar -
Linux下的壓縮&解壓命令
【tar命令】 解壓:tar -zxvf FileName.tar 壓縮:tar -czvf FileName.tar DirName 【gz命令】 解壓1:gunzip FileName.gz 解壓2:gzip -d FileName.gz 壓
淺談Linux下各種壓縮 解壓命令和壓縮比率對比
轉載,收藏 tar命令是linux下非常常用的命令,這篇文章對該命令介紹的比較詳細,因此轉載加收藏吧。 Linux下壓縮、解壓命令五花八門,不像在windows下一個winrar打遍天下無敵手,清一色的.rar .zip格式。比如,Linux下常用的tar tar.gz
關於linux下壓縮解壓
tar-c: 建立壓縮檔案-x:解壓-t:檢視內容-r:向壓縮歸檔檔案末尾追加檔案-u:更新原壓縮包中的檔案這五個是獨立的命令,壓縮解壓都要用到其中一個,可以和別的命令連用但只能用其中一個。下面的引數是根據需要在壓縮或解壓檔案時可選的。-z:有gzip屬性的-j:有bz2屬性
linux系統下tar/gz/7z/xz/bz2/zip等各種格式的打包壓縮解壓
linux系統下總會遇到各種格式的壓縮包,什麼tar/gz/7z/xz/bz2/zip等等,每種格式檔案的解壓和壓縮方法都不完全一致,所攜帶的引數也都各有千秋,初學者往往會一臉茫然,不知如何是好。於是,本文就對上述各種常見的檔案和命令進行一番總結和對比,以便查閱
Linux下檔案壓縮解壓
對於剛剛接觸Linux的人來說,一定會給Linux下一大堆各式各樣的檔名給搞暈。別個不說,單單就壓縮檔案為例,我們知道在Windows下最常見的壓縮檔案就只有兩種,一是,zip,另一個是.rap。可是Linux就不同了,它有.gz、.tar.gz、tgz、bz2、.Z、.ta
Qt實現zip壓縮和解壓,編譯、呼叫zlib和QuaZip動態庫過程詳解
http://blog.csdn.net/qq_37354286/article/details/78858788之前有個小專案中需要對zip壓縮檔案進行壓縮和解壓操作,需要用到zlib庫,使用Qt開發的話可以用到已經封裝好的QuaZip。作為一枚新人程式設計師應有的習慣,我
linux下打壓縮解壓
獨立 表示 屬性 末尾 jpg 一個 並且 輸出 中一 tar -c: 建立壓縮檔案-x:解壓-t:查看內容-r:向壓縮歸檔文件末尾追加文件-u:更新原壓縮包中的文件 這五個是獨立的命令,壓縮解壓都要用到其中一個,可以和別的命令連用但只能用其中一個。下面的參數是根據需要