如果保存数据,libz压缩失败

时间:2013-11-01 10:51:05

标签: c++ zlib

我刚刚遇到了 libz 的一个奇怪的行为。如果我只使用压缩功能,一切正常,但如果我尝试例如。将压缩数据保存到文件我得到 Z_BUF_ERROR 。我做错了什么?

#include <iostream>
#include <fstream>

#include "zlib.h"

typedef unsigned char byte_t;

static int read_filesize(const char* filename) {
    int size = -1;
    std::ifstream file(filename);
    if (!file.is_open()) return size;

    file.seekg(0, std::ios::end);
    size = (int) file.tellg();
    file.close();

    return size;
}

static bool read_binary_file(const char* filename, byte_t* dst, const unsigned length) {
    std::ifstream file(filename, std::ios::binary);
    if (!file.is_open()) return false;

    file.read((char*) dst, length);
    file.close();

    return true;
}

static bool save_binary_file(const char* filename, const byte_t* src, const unsigned length) {
    std::ofstream file(filename, std::ios::binary);
    if (!file.is_open()) return false;

    file.write((const char*) src, length);
    file.close();

    return true;
}

int main(int args, char **argv) {
    int fileSize = read_filesize(argv[1]);
    byte_t fileData[fileSize];
    bool result = read_binary_file(argv[1], fileData, fileSize);

    unsigned compressedSize = compressBound(fileSize);
    byte_t compressed[compressedSize]; 

    int compressionResult = compress(compressed, (unsigned long*) &compressedSize, fileData, fileSize);

    switch (compressionResult) {
    case Z_OK:
        std::cout << "Compression succeeded!\n";
        break;

    case Z_MEM_ERROR:
        std::cout << "Error: Z_MEM_ERROR!\n";
        return 1;

    case Z_BUF_ERROR:
        std::cout << "Error: Z_BUF_ERROR!\n";
        return 1;

    default:
        std::cout << "Error: UNDEFINED!\n";
        return 1;
    }

    std::cout << "Size of '" << argv[1] << "': " << fileSize << "\n"
            << "After: " << compressedSize << "\n";

    bool saveResult = save_binary_file("file.bin.z", compressed, compressedSize);  // everything works if I remove this instruction

    return 0;
}

3 个答案:

答案 0 :(得分:3)

从上面的评论中可以看出,您使用的是64位架构sizeof(unsigned long)==8,而sizeof(unsigned)==4

因此,(unsigned long*)&compressedSize compressedSize的类型为unsigned,会产生未定义的行为。

只需将compressedSize的声明更改为unsigned long,即可解决此问题。

答案 1 :(得分:0)

堆栈溢出?我不知道如何在g ++中实现动态数组,但如果将它们放在堆栈中,则可能会遇到大文件问题。使用std::vectorstd::array

答案 2 :(得分:0)

int fileSize = read_filesize(argv[1]);
byte_t fileData[fileSize];

这是一个VLA(可变长度数组)。不得使用它们。使用std :: vector代替。 同样适用于compressed