首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何压缩QByteArray?

如何压缩QByteArray?
EN

Stack Overflow用户
提问于 2012-01-10 21:40:46
回答 3查看 8.6K关注 0票数 7

在压缩文本时,我希望维护地球上其他应用程序(包括web应用程序)之间的互操作性。由于qCompress和qUncompress似乎背道而驰,所以我尝试直接从Qt应用程序中使用zlib。

我将接受最简单(最简单)的答案,它向我展示了如何使用带有QByteArray的的zlib库,修改qCompress的输出,以便它可以在Qt应用程序之外使用。

下面是我尴尬的尝试:

代码语言:javascript
复制
QByteArray tdata = QString("Oh noes!").toUtf8();
QByteArray cdata;
uLongf len = 12 + 1.002*tdata.length();
compress(&cdata, &len, &tdata, tdata.length());

而错误是:

错误:不能将参数'1‘的'QByteArray*’转换为'Bytef*‘到'int compress’( Bytef*,uLongf*,const *,uLong)‘

然后,我尝试使用QByteArray::constData()

代码语言:javascript
复制
compress(cdata.constData(), &len, &tdata, tdata.length());

但是得到了以下错误:

错误:从“const char*”到“Bytef*”的转换无效

我不知道Bytef是什么,所以我开始在zlib源代码中进行调查。但我所能找到的只有QtSources/src/3 3rdparty/zlib/zconf.h.h

代码语言:javascript
复制
# define Bytef                 z_Bytef

所以现在我迷路了。

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2012-01-10 22:12:21

根据在qUncompress中的注释,我认为这很容易。

注意:如果您想使用这个函数来解压缩使用zlib压缩的外部数据,那么首先需要在包含数据的字节数组中添加一个4字节的头。报头必须包含未压缩数据的预期长度(以字节为单位),表示为无符号、大端、32位整数。

所以你可以像这样压缩它:

代码语言:javascript
复制
QByteArray tdata = QString("Oh noes!").toUtf8();
QByteArray compressedData = qCompress(tdata);
compressedData.remove(0, 4);
票数 8
EN

Stack Overflow用户

发布于 2012-01-10 21:49:34

下面是我曾经编写的一些代码,这些代码作为输入获取指向字节数组的指针、要压缩的字节数和压缩级别,然后使用zlib压缩输入。结果以字符串形式返回。

代码语言:javascript
复制
 enum compressionLevel
 {
    clFast,
    clSmall,
    clDefault
 };

 const size_t ChunkSize = 262144; //256k default size for chunks fed to zlib

 void compressZlib(const char *s, size_t nbytes, std::string &out, compressionLevel l /*= clDefault*/ )
 {
    int level = Z_DEFAULT_COMPRESSION;
    switch (l)
    {
    case clDefault:
        level = Z_DEFAULT_COMPRESSION; break;
    case clSmall:
        level = Z_BEST_COMPRESSION; break;
    case clFast:
        level = Z_BEST_SPEED; break;
    };

    z_stream strm;
    strm.zalloc = Z_NULL;
    strm.zfree = Z_NULL;
    strm.opaque = Z_NULL;
    int ret = deflateInit(&strm, level);
    if (ret != Z_OK)
    {
        throw std::runtime_error("Error while initializing zlib, error code "+ret);
    }
    size_t toCompress = nbytes;
    char *readp = (char*)s;
    size_t writeOffset = out.size();
    out.reserve((size_t)(nbytes * 0.7));
    while (toCompress > 0)
    {
        size_t toRead = std::min(toCompress,ChunkSize);
        int flush = toRead < toCompress ? Z_NO_FLUSH : Z_FINISH;
        strm.avail_in = toRead;
        strm.next_in = (Bytef*)readp;
        char *writep = new char[ChunkSize];
        do{
            strm.avail_out = ChunkSize;
            strm.next_out = (Bytef*)writep;
            deflate(&strm, flush);
            size_t written = ChunkSize - strm.avail_out;
            out.resize(out.size() + written);
            memcpy(&(out[writeOffset]), writep, written);
            writeOffset += written;
        } while (strm.avail_out == 0);
        delete[] writep;
        readp += toRead;
        toCompress -= toRead;
    }
    (void)deflateEnd(&strm);
 }

也许这可以帮助您解决问题,我想使用cdata.constData()可以直接调用这个函数

票数 1
EN

Stack Overflow用户

发布于 2012-01-10 22:20:17

只是为了帮你解决问题的最后一部分:

我不知道Bytef是什么,所以我开始在zlib源代码中进行调查。

有关ByteBytef的定义,请参阅zconf.h .h的第332和333行以及第342行:

代码语言:javascript
复制
332    #if !defined(__MACTYPES__)
333    typedef unsigned char  Byte;  /* 8 bits */
...
338    #ifdef SMALL_MEDIUM
339       /* Borland C/C++ and some old MSC versions ignore FAR inside typedef */
340    #  define Bytef Byte FAR
341    #else
342       typedef Byte  FAR Bytef;    

FAR的定义是用于混合模式的MSDOS编程,否则它不会被定义为任何东西(参见zcon.h第328-330行)。

因此,zlib类型的BytefByte与大多数平台上的unsigned char基本相同。因此,您应该能够-执行以下操作:

代码语言:javascript
复制
QByteArray tdata = QString("Oh noes!").toUtf8();
QByteArray cdata(compressBound(tdata.length()), '\0');
uLongf len = compressBound(tdata.length());
compress(reinterpret_cast<unsigned char*>(cdata.data()), &len, 
         reinterpret_cast<unsigned char*>(tdata.data()), tdata.length());
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/8810897

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档