如何解压缩gzip流

 我来答
匿名用户
推荐于2016-02-11
展开全部
namespace NExtractZip
{
void ExtractionExampleL(const TDesC& aCompressedFile, const TDesC& aPath, const TDesC& aFileName)
{
if(!IteratorExampleL(aCompressedFile, aFileName)) { return; }

// Connect to the file server.
RFs fileSession;
User::LeaveIfError(fileSession.Connect());

// Create an instance of CZipFile.
CZipFile* zipFile = CZipFile::NewL(fileSession, aCompressedFile);
CleanupStack::PushL(zipFile);

// Get the input stream of aFileName.
CZipFileMember* member = zipFile->CaseInsensitiveMemberL(aFileName);
CleanupStack::PushL(member);
RZipFileMemberReaderStream* stream;
zipFile->GetInputStreamL(member, stream);
CleanupStack::PushL(stream);

// Extracts aFileName to a buffer.
// If the file is quite huge, then read the file in streaming mode.
// For example, use 4KB buffer and read it in an active object.
HBufC8* buffer = HBufC8::NewLC(member->UncompressedSize());
TPtr8 bufferPtr(buffer->Des());
User::LeaveIfError(stream->Read(bufferPtr, member->UncompressedSize()));

// Store the buffer to a file.
// It saves the file to KExtractedPath directory, the file name is the same
// as the one in the .zip file.
TFileName fileName;
fileName.Append(aPath);
fileName.Append(aFileName);
RFile file;
User::LeaveIfError(file.Replace(fileSession, fileName, EFileWrite));
CleanupClosePushL(file);
User::LeaveIfError(file.Write(*buffer));

// Release all the resources.
CleanupStack::PopAndDestroy(5); // file, buffer, stream, member, zipFile
fileSession.Close();
}
}

但是现在我需要的是解压gzip流,这个流是没有文件“头”和“尾”的,见下面的描述:

GZIP最早由Jean-loup Gailly和Mark Adler创建,用于UNIX系统的文件压缩。我们在Linux中经常会用到后缀为.gz的文件,它们就是GZIP格式的。现今已经成为Internet上使用非常普遍的一种数据压缩格式,或者说一种文件格式。HTTP协议上的GZIP编码是一种用来改进WEB应用程序性能的技术。大流量的WEB站点常常使用GZIP压缩技术来让用户感受更快的速度。

GZIP本身只是一种文件格式,其内部通常采用DEFLATE数据格式,而DEFLATE采用LZ77压缩算法来压缩数据。

GZIP文件由1到多个“块”组成,实际上通常只有1块。每个块包含头、数据和尾三部分。块的概貌如下:

+---+---+---+---+---+---+---+---+---+---+========//========+===========//==========+---+---+---+---+---+---+---+---+
|ID1|ID2| CM|FLG| MTIME |XFL| OS| 额外的头字段 | 压缩的数据 | CRC32 | ISIZE |
+---+---+---+---+---+---+---+---+---+---+========//========+===========//==========+---+---+---+---+---+---+---+---+

压缩二进制到gzip流和解压还原内容是由java源码的,现在想知道的是,如果不翻译这个源码,symbian是否有什么方法可以解压呢?

网上还有一段代码是:

CBufFlat* nOutBuf = CBufFlat::NewL(128);
CBufferManager *nBufferManager = CBufferManager::NewLC(aBodyData, *nOutBuf, 128);
CEZDecompressor *decompressor = CEZDecompressor::NewLC(*nBufferManager);
while (decompressor->InflateL())
{
// loop here until the file is decompressed
} // *****(1)
CleanupStack::PopAndDestroy(2); //decompressor, bufManager //*****(2)

CBufferManager 也有人公开了源码, 但是我实际调试了一下,断点// *****(1)之后执行不到//*****(2)。
在CBufferManager 里调试也看不出所以然来,哪位高手做过类似的工作么?有没有运行通过的CBufferManager 类供参考呢。
网上找到的java解压gzip流 GZipOutputStream.java、GZipInputStream.java 是可以解压的。

class CBufferManager : public CBase, public MEZBufferManager
{
public:
static CBufferManager* NewLC(const TDesC8& aInput, CBufFlat& aOutput, TInt aBufferSize = 64);
static CBufferManager* NewL(const TDesC8& aInput, CBufFlat& aOutput, TInt aBufferSize = 64);
~CBufferManager();

private:
CBufferManager(CBufFlat& aOutput);
void ConstructL(const TDesC8& aInput, TInt aBufferSize);

public: //from MEZBufferManager
void InitializeL(CEZZStream &aZStream);
void NeedInputL(CEZZStream &aZStream);
void NeedOutputL(CEZZStream &aZStream);
void FinalizeL(CEZZStream &aZStream);

private:
HBufC8* iInput;
CBufFlat& iOutput;

TInt iBufferSize;

TUint8* iInputBuffer;
TUint8* iOutputBuffer;

TPtr8 iInputDescriptor; // always points to start of the input Buffer
TPtr8 iOutputDescriptor; // always points to start of the output Buffer
};

这是java的一段代码:
/**
*
* @param outputStream stream to write the compressed data in
* @param size prefered size of the internal buffer
* @param compressionType TYPE_GZIP or TYPE_DEFLATE
* @param plainWindowSize this size is important for the lz77 search. Larger values
* will result in better compression. Maximum is 32768.
* @param huffmanWindowSize this size is important for the huffmanencoding. A large
* value will result to a better frequency statistic and therefore to a better compression.
* @throws IOException might be thrown in case that the inputStream can not be read,
* the outputStream can not be written into or in case of wrong arguments
*
* @see #TYPE_DEFLATE
* @see #TYPE_GZIP
*/
public GZipOutputStream(OutputStream outputStream, int size, int compressionType, int plainWindowSize, int huffmanWindowSize) throws IOException {
this.outStream = outputStream;

this.inputBuffer=new byte[size+300];
this.litCount=new int[286];
this.distCount=new int[30];
this.smallCodeBuffer = new int[2];

// check plainWindowSize; this triggers the LZ77 compression
if (plainWindowSize > 32768){
throw new IllegalArgumentException("plainWindowSize > 32768");
}
if (plainWindowSize>=100){
this.plainDataWindow = new byte[(plainWindowSize/HASHMAP_COUNT)*HASHMAP_COUNT];
this.lz77active=true;
} else {
this.plainDataWindow=null;
this.lz77active=false;
}

// check the huffmanWindowSize; this also triggers dynamic/fixed trees
if (huffmanWindowSize > 32768){
throw new IllegalArgumentException("plainWindowSize > 32768");
}
if (huffmanWindowSize<1024 && huffmanWindowSize>0){
huffmanWindowSize=1024;
}
this.outputWindow = new byte[huffmanWindowSize];
if(huffmanWindowSize==0){
this.lastBlock=true;
// fixed tree: write header, generate huffman codes
this.BTYPE=1;
newBlock();
this.status=GZipOutputStream.STREAMING;
} else {
this.BTYPE=2;
this.status=GZipOutputStream.STREAM_INIT;
}

for (int i = 0; i < HASHMAP_COUNT; i++) {
this.HM[i] = new ZipIntMultShortHashMap(2*1024);
}

// write GZIP header, if wanted
if (compressionType==GZipOutputStream.TYPE_GZIP){
/*
+---+---+---+---+---+---+---+---+---+---+
|ID1|ID2|CM |FLG| MTIME |XFL|OS |
+---+---+---+---+---+---+---+---+---+---+*/
this.outStream.write(31);
this.outStream.write(139);
this.outStream.write(8);
this.outStream.write(new byte[6]);
this.outStream.write(255);
}

}
更多0
本回答被提问者和网友采纳
已赞过 已踩过<
你对这个回答的评价是?
评论 收起
收起 1条折叠回答
推荐律师服务: 若未解决您的问题,请您详细描述您的问题,通过百度律临进行免费专业咨询

为你推荐:

下载百度知道APP,抢鲜体验
使用百度知道APP,立即抢鲜体验。你的手机镜头里或许有别人想知道的答案。
扫描二维码下载
×

类别

我们会通过消息、邮箱等方式尽快将举报结果通知您。

说明

0/200

提交
取消

辅 助

模 式