2013-02-08 267 views
0

我有一个代码工作,但我并不完全满意的结果,所以我想我可以在这里问一些问题。lzma压缩/从内存解压C++

这里是我的两个功能:

void compress(string nameSrc, string nameDst){ 

    ifstream input; 
    input.open(nameSrc,fstream::in | fstream::binary); 

    size_t propsSize = LZMA_PROPS_SIZE; 
    size_t srcLen = getLength(input); 
    size_t dstLen = srcLen; //??? no idea how to know to right value here 

    unsigned char* src = new unsigned char[srcLen]; 
    unsigned char* dst = new unsigned char[dstLen + propsSize]; 

    input.read((char*)src, srcLen); 

    int res = LzmaCompress(
     &dst[LZMA_PROPS_SIZE], &dstLen, 
     src, srcLen, 
     dst, &propsSize, 
     -1, 0, -1, -1, -1, -1, -1); 

    delete [] src; 
    input.close(); 

    ofstream output(nameDst, ios::binary); 
    output.write((char*)dst, dstLen + propsSize); 

    delete [] dst; 


} 

和:

void unCompress(string nameSrc, string nameDst){ 

    ifstream input; 
    input.open(nameSrc,fstream::in | fstream::binary); 

    size_t srcLen = getLength(input); 
    size_t dstLen = srcLen*5; //??? no idea how to know to right value here 

    unsigned char* src = new unsigned char[srcLen]; 
    unsigned char* dst = new unsigned char[dstLen]; 

    input.read((char*)src,srcLen); 

    int res = LzmaUncompress(dst,&dstLen,&src[LZMA_PROPS_SIZE],&srcLen, src, LZMA_PROPS_SIZE); 

    delete [] src; 
    input.close(); 

    ofstream output(nameDst, ios::binary); 
    output.write((char*)dst, dstLen); 

    delete [] dst; 
} 

  1. 在这两种功能,我怎么知道该怎么把价值为dstLen?我不想分配很多内存。
  2. 难道我必须转换成char *吗?我真的必须使用unsigned char吗?
  3. 我试着改变LzmaCompress(numThreads)的最后一个参数,它没有改善性能,甚至没有改善。还有其他事情要做吗?
  4. 如果您有任何提示,请随时告诉我。

谢谢。

+1

那么,什么是这些'LZMA * ompress()'函数,他们在哪里来的呢?有没有关于他们的文件?虽然我可以想象后处理的大小可能是未知的(特别是对于压缩),但压缩数据可能包含应该易于提取的原始大小。文档和压缩算法的解释也应该给你一个'numThreads'参数的概念,无论它是否有用(某些压缩/解压缩算法本身是连续的并且不能并行化)。 –

+0

他们来自LZMA SDK(http://www.7-zip.org/sdk.html)。是的,一旦数据被压缩,我就可以知道尺寸。我的问题是,我必须在此之前分配内存。 – user1278743

回答

1

使用下面的函数来获得目标尺寸:

INT32 
EFIAPI 
LzmaGetInfo(
CONST VOID *Source, 
UINT32  SourceSize, 
UINT32  *DestinationSize 
) 
{ 
    UInt64 DecodedSize; 

    ASSERT(SourceSize >= LZMA_HEADER_SIZE); (void)SourceSize; 

    DecodedSize = GetDecodedSizeOfBuf((UINT8*)Source); 

    *DestinationSize = (UINT32)DecodedSize; 
    return ERR_SUCCESS; 
}