7-zip 下lzma資料解壓縮方式
那些踩過得神坑:<備註,這個demo的例子有一處是不對的.>
LzmaDecode中的第四個引數:nCompBufLen
應該給第三個引數的實際緩衝區大小.!!!,我操.分析原始碼.和返回值,百度沒有.
本文章介紹的是 LZMA SDK 9.20
7z LZMA 至少需要這三個原始檔
LzmaEnc.c
LzmaDec.c
LzFind.c
和這五個標頭檔案
LzFind.h
LzHash.h
LzmaDec.h
LzmaEnc.h
Types.h
LZMA2 需要在此基礎上附加兩個原始檔
Lzma2Dec.c
Lzma2Enc.c
以及兩個標頭檔案
Lzma2Dec.h
Lzma2Enc.h
LZMA 流介面有 6 個函式,引數含義可顧名思義
CLzmaEncHandle LzmaEnc_Create(ISzAlloc *alloc);
void LzmaEnc_Destroy(CLzmaEncHandle p, ISzAlloc *alloc, ISzAlloc *allocBig);
SRes LzmaEnc_SetProps(CLzmaEncHandle p, const CLzmaEncProps *props);
SRes LzmaEnc_WriteProperties(CLzmaEncHandle p, Byte *properties, SizeT *size);
SRes LzmaEnc_Encode(CLzmaEncHandle p, ISeqOutStream *outStream, ISeqInStream *inStream,
ICompressProgress *progress, ISzAlloc *alloc, ISzAlloc *allocBig);
SRes LzmaEnc_MemEncode(CLzmaEncHandle p, Byte *dest, SizeT *destLen, const Byte *src, SizeT srcLen,
int writeEndMark, ICompressProgress *progress, ISzAlloc *alloc, ISzAlloc *allocBig);
CLzmaEncHandle 實為 void *
SRes 為狀態返回型別
ISzAlloc、ISeqInStream、ISeqOutStreaem 和 ICompressProgress 為使用者需要提供的四個介面,它們的定義如下
typedef struct
{
void *(*Alloc)(void *p, size_t size);
void (*Free)(void *p, void *address); /* address can be 0 */
} ISzAlloc;
typedef struct
{
SRes (*Read)(void *p, void *buf, size_t *size);
/* if (input(*size) != 0 && output(*size) == 0) means end_of_stream.
(output(*size) < input(*size)) is allowed */
} ISeqInStream;
typedef struct
{
size_t (*Write)(void *p, const void *buf, size_t size);
/* Returns: result - the number of actually written bytes.
(result < size) means error */
} ISeqOutStream;
typedef struct
{
SRes (*Progress)(void *p, UInt64 inSize, UInt64 outSize);
/* Returns: result. (result != SZ_OK) means break.
Value (UInt64)(Int64)-1 for size means unknown value. */
} ICompressProgress;
另外注意在實現 ISeqInStream 時,除最後兩次呼叫外,必須每次都提交 *size 位元組的資料,最後兩次中,一次提交所有剩餘資料,另一次提交 0 位元組表示結束,否則 LZMA Encoder 會崩潰。
還有一個 One-Call 介面,把上面的呼叫按照常規邏輯包裝了一下
SRes LzmaEncode(Byte *dest, SizeT *destLen, const Byte *src, SizeT srcLen,
const CLzmaEncProps *props, Byte *propsEncoded, SizeT *propsSize, int writeEndMark,
ICompressProgress *progress, ISzAlloc *alloc, ISzAlloc *allocBig);
LZMA2 的介面與 LZMA 類似,主要不同之處有兩點:
- alloc 和 allocBig 介面被放到了建構函式中
- props 中多了一些引數
http://www.7-zip.org/sdk.html
另外值得一提的是,LZMA 單執行緒在筆記本電池供電時,使用快速模式,對隨機資料的壓縮速度為 4MB/s,壓縮率約為 100%,對全零資料的壓縮速度為 70MB/s,壓縮率約為 0%。
經過SunOS sun280 5.10驗證的例項(該例項為直接呼叫封裝好的函式):
/* * Simple test program for LZMA SDK's "one call" interface. * */ #include <stdio.h> #include <string.h> #include "../../LzmaEnc.h" #include "../../LzmaDec.h" #include "../../Alloc.h" #define COMP_BUFLEN 1000 #define UNCOMP_BUFLEN 5000 char* pTestData; unsigned char pCompBuf[1000]; /* Compressed data */ unsigned char pUnCompBuf[5000]; /* Unompressed data - at the end its contents */ /* should be equal to contents of pTestData */ static void *SzAlloc(void *p, size_t size) { return MyAlloc(size); } static void SzFree(void *p, void *address) { MyFree(address); } int main(int argc, char* argv[]) { pTestData = "DEADBEEF|askjd9827x34bnzkj#%wioeruxo3b84nxijlhwqdzhwerzu39b87r#_3b9p78bznor83y4fr"; size_t nTestDataLen = strlen(pTestData); size_t nCompBufLen = COMP_BUFLEN; size_t nUnCompBufLen = UNCOMP_BUFLEN; unsigned char pPropsBuf[LZMA_PROPS_SIZE]; size_t nPropsBufLen = LZMA_PROPS_SIZE; ISzAlloc stAllocator = { SzAlloc, SzFree }; CLzmaEncProps stProps; ELzmaStatus nStatus; SRes rc; int err = 0; memset(pCompBuf, 0, COMP_BUFLEN); memset(pUnCompBuf, 0, UNCOMP_BUFLEN); /* Initialize compressor (aka encoder) properties... */ LzmaEncProps_Init(&stProps); stProps.level = 9; stProps.dictSize = 1 << 24; /* ... and compress data. */ printf("dest_len:%d,src_len:%d,prop_len:%d\n",nCompBufLen,nTestDataLen,nPropsBufLen); rc = LzmaEncode(pCompBuf+LZMA_PROPS_SIZE, &nCompBufLen, (unsigned char*)pTestData, nTestDataLen, &stProps, pPropsBuf, &nPropsBufLen, 0, NULL, &stAllocator, &stAllocator); if ( rc != SZ_OK ) { printf("\nLZMA compression failed (rc=%d).\n", rc); err = 1; } else { printf("dest_address:%p,dest_len:%d,src_len:%d,dest:%s\n",pCompBuf,nCompBufLen,nTestDataLen,pCompBuf+LZMA_PROPS_SIZE+1); } /* Decompress compressed data from previous step */ //nCompBufLen += LZMA_PROPS_SIZE; nUnCompBufLen = nTestDataLen; rc = LzmaDecode(pUnCompBuf, &nUnCompBufLen, pCompBuf+LZMA_PROPS_SIZE, &nCompBufLen, pPropsBuf, nPropsBufLen, LZMA_FINISH_ANY, &nStatus, &stAllocator); if ( rc != SZ_OK ) { printf("\nLZMA decompression failed (rc=%d, status=%d).\n", rc, nStatus); err = 1; } if ((nUnCompBufLen != nTestDataLen) || memcmp(pTestData, pUnCompBuf, nTestDataLen) ) { printf("Compression and/or decompression failed!\n"); printf("\tInput data length [nTestDataLen] : %d\n", nTestDataLen); printf("\tCompressed data length [nCompBufLen] : %d\n", nCompBufLen); printf("\tUncompressed data length [nUnCompBufLen]: %d\n", nUnCompBufLen); if ( memcmp(pTestData, pUnCompBuf, nTestDataLen) ) printf("\tpTestData and pUnCompBuf contain different data!\n"); else { printf("\ndest_len:%d\n,dest_data:%s\n,src_src:%s\n",nUnCompBufLen,pUnCompBuf,pTestData); } err = 1; } printf("\ndest_len:%d\n,dest_data:%s\n,src_src:%s\n",nUnCompBufLen,pUnCompBuf,pTestData); if ( !err ) printf("\nOK!\n"); return 0; }
詳情請瀏覽sdk說明文件或者LZMA官方論壇(http://sourceforge.net/projects/sevenzip/forums/forum/45797/topic/4698263)
備註:
整整三天才搞出來,今天終於可以好好睡覺了。學程式設計的同學啊,要加強英語的學習啊。
原文轉載自:http://blog.163.com/[email protected]/blog/static/1018865812012499356225/
相關推薦
7-zip 下lzma資料解壓縮方式
那些踩過得神坑:<備註,這個demo的例子有一處是不對的.> LzmaDecode中的第四個引數:nCompBufLen 應該給第三個引數的實際緩衝區大小.!!!,我操.分析原始碼.和返回值,百度沒有. 本文章介紹的是 LZMA SDK 9.20 7z
CentOS 下安裝7-Zip 以及常用的解壓命令
在SHH或者終端下輸入:yum –y install p7zip(如果提示找不到資源,則要自己下載編譯安裝,命令如:) wget http://nchc.dl.sourceforge.net/sourceforge/p7zip/p7zip_4.65_src
tar、zip、gzip等解壓縮命令
解壓縮tar命令:壓縮:tar cf 壓縮後的文件名.tar.gz 壓縮前的文件或者目錄解壓:tar xf 壓縮後的文件名.tar.gz查看壓縮裏的內容:tar tf 壓縮後的文件名.tar.gz zip命令:壓縮目錄:zip –r /opt/etc.zip /etc 解壓:unzip /opt/etc.
LearnPython - Zip格式檔案的解壓縮
1 import zipfile 2 import os 3 4 5 def unzip(zip_name, target_dir): 6 files = zipfile.ZipFile(zip_name) 7 for zip_file in files.namelis
對稱矩陣壓縮和三種解壓縮方式
#include<iostream> #include<stdio.h> #include<math.h> #define SIZE 5 using namespace std; int* Compress(int *m) { int*n = (
ubuntu下建立資料夾快捷方式
title: ubuntu下建立資料夾快捷方式 toc: false date: 2018-09-01 17:22:28 categories: methods tags: ubuntu 快捷方式 sudo ln -sT [srcDir] [dstDir/name]
linux中 gzip bizp2 xz zip怎麼用,解壓縮
linux 中常用的壓縮指令 壓縮 gzip bzip2 xz , 解壓gunzip unxz bunzip2 解壓對應的壓縮包 *.tar.gz *.tar.xz *.tar.bz2(由於 compress 效率底下,已經丟棄不用啦) 選項
Windows下安裝MySQL解壓縮版
1.去官網下載.zip格式的MySQL Server的壓縮包,根據需要選擇x86或x64版。 2.解壓縮至你想要的位置。 3.在解壓檔案目錄下新建空白檔案,重新命名為my.ini。並新增以下內容(路徑要根據自己的情況修改呀)。沒有data目錄不要緊,下一步處理這個事情
Java解壓縮zip檔案工具類(支援zip資料夾下多級目錄結構)
文章目錄 Java解壓縮zip檔案工具類(支援zip資料夾下多級目錄結構) 1. 前言 2. 正文 2.1 解壓縮後文件目錄結構展示 2.2 注意事項 2.3 異常
Linux下的壓縮zip,解壓縮unzip命令詳解及實例
cnblogs http .com 服務器 file html htm unzip inux http://www.cnblogs.com/zdz8207/p/3765604.html Linux下的壓縮解壓縮命令詳解及實例 實例:壓縮服務器上當前目錄的內容為xx
WIN 10下Mysql 5.7.21解壓縮(免安裝版)配置
控制 roo 5.7 ogr 很多 mysql 5.7 mysql數據庫 l數據庫 服務 網上看了N多大神的東西東抄抄西抄抄,老是就不對,因為很多資料不是針對5.7這個版本的內容。 首先解壓文件,比如我解壓到D:\Program Files\mysql-5.7.21-wi
zip壓縮/解壓縮帶空資料夾的檔案
zip壓縮/解壓縮帶空資料夾的檔案 2011年07月21日 20:04:54 flex_work 閱讀數:7152 標籤: filestringbytebuffernullinclude 更多 個人分類: Flex And Java
CentOS5/6/7系統下搭建安裝Amabari大資料叢集時出現SSLError: Failed to connect. Please check openssl library versions.錯誤的解決辦法(圖文詳解)
不多說,直接上乾貨! ========================== Creating target directory... ======================
window 10 下解壓縮版MySQL5.7.24的安裝
安裝步驟: 1.下載mysql-5.6.40-winx64.zip https://cdn.mysql.com//Downloads/MySQL-5.7/mysql-5.7.24-winx64.zip 2.解壓mysql5.7.24 3.配置mysql的環境變數 在path中新增:;D:\mysql
WINDOWS下MySQL 5.7+ 解壓縮版安裝配置方法
1.去官網下載.zip格式的MySQL Server的壓縮包,根據需要選擇x86或x64版。注意:下載是需要註冊賬戶並登入的。 2.解壓縮至你想要的位置。 3.複製解壓目錄下my-dafault.ini至bin目錄下,重新命名為my.ini。並新增以下內容(路徑要根據自己的情況修改呀)。沒有data目錄不
Linux 下壓縮與解壓縮 zip、binzip2、tar、zip命令的使用
我們經常需要對檔案壓縮或打包實現統一管理,下面就讓我們來看看gzip、bzip2、tar、zip這些命令的使用 (1) gzip 格式:gzip [選項] [檔案] 示例: ---在testzip目錄下有以下檔案 --
Linux下的壓縮zip,tar命令詳解及例項
Linux下的壓縮解壓縮命令詳解及例項 例項:壓縮伺服器上當前目錄的內容為xxx.zip檔案 zip -r xxx.zip ./* 解壓zip檔案到當前目錄 unzip filename.zip ============================ 另:有些伺服器
Linux下解壓命令大全 解壓縮 tar bz2 zip tar.gz gz
大致總結了一下linux下各種格式的壓縮包的壓縮、解壓方法。但是部分方法我沒有用到,也就不全,希望大家幫我補充,我將隨時修改完善,謝謝!整理:會游泳的魚 來自:www.LinuxByte.net 最後更新時間:2005-2-20 .tar 解包:tar xvf FileName.tar 打包:tar cvf
Linux下tar.gz、tar、bz2、zip等格式解壓縮、壓縮命令小結
Linux下最常用的打包程式就是tar了,使用tar程式打出來的包我們常稱為tar包,tar包檔案的命令通常都是以.tar結尾的。生成tar包後,就可以用其它的程式來進行壓縮了,所以首先就來講講tar命令的基本用法: tar命令的選項有很多(用man tar可以檢視到),但常用的就那麼幾個選項,下面 來舉
linux下tar.gz、tar、bz2、zip等解壓縮、壓縮命令小結
Linux下最常用的打包程式就是tar了,使用tar程式打出來的包我們常稱為tar包,tar包檔案的命令通常都是以.tar結尾的。生成tar包後,就可以用其它的程式來進 行壓縮了,所以首先就來講講tar命令的基本用法: tar命令的選項有很多(用man tar可以檢視到