c++ Zlib写入文件不工作

c++ Zlib fwrite to file not working

本文关键字:工作 文件 Zlib c++      更新时间:2023-10-16

我有这个程序,我正在工作,简单地做以下操作:

  1. 打开压缩文件
  2. 解压成std::string
  3. 从std::string压缩
  4. 另存为gzip文件

然而,我似乎不能在最后写入压缩的数据。我得到的错误是:没有匹配的函数调用'fwrite'。

我是否为它提供了错误的参数?或者输入错误的类型?

完整的过程如下:

#include <iostream>
#include "zlib-1.2.8/zlib.h"
#include <stdexcept>
#include <iomanip>
#include <sstream>
#include <stdio.h>
#include <assert.h>
#include <cstdio>
#include <string>
#include <cstring>
#include <cstdlib>
#include "zlib.h"
#include "zconf.h"
#if defined(MSDOS) || defined(OS2) || defined(WIN32) || defined(__CYGWIN__)
#  include <fcntl.h>
#  include <io.h>
#  define SET_BINARY_MODE(file) setmode(fileno(file), O_BINARY)
#else
#  define SET_BINARY_MODE(file)
#endif
#define CHUNK 16384
using namespace std;
bool gzipInflate( const std::string& compressedBytes, std::string& uncompressedBytes ) {
    if ( compressedBytes.size() == 0 ) {
        uncompressedBytes = compressedBytes ;
        return true ;
    }
    uncompressedBytes.clear() ;
    unsigned full_length = compressedBytes.size() ;
    unsigned half_length = compressedBytes.size() / 2;
    unsigned uncompLength = full_length ;
    char* uncomp = (char*) calloc( sizeof(char), uncompLength );
    z_stream strm;
    strm.next_in = (Bytef *) compressedBytes.c_str();
    strm.avail_in = compressedBytes.size() ;
    strm.total_out = 0;
    strm.zalloc = Z_NULL;
    strm.zfree = Z_NULL;
    bool done = false ;
    if (inflateInit2(&strm, (16+MAX_WBITS)) != Z_OK) {
        free( uncomp );
        return false;
    }
    while (!done) {
        // If our output buffer is too small
        if (strm.total_out >= uncompLength ) {
            // Increase size of output buffer
            char* uncomp2 = (char*) calloc( sizeof(char), uncompLength + half_length );
            memcpy( uncomp2, uncomp, uncompLength );
            uncompLength += half_length ;
            free( uncomp );
            uncomp = uncomp2 ;
        }
        strm.next_out = (Bytef *) (uncomp + strm.total_out);
        strm.avail_out = uncompLength - strm.total_out;
        // Inflate another chunk.
        int err = inflate (&strm, Z_SYNC_FLUSH);
        if (err == Z_STREAM_END) done = true;
        else if (err != Z_OK)  {
            break;
        }
    }
    if (inflateEnd (&strm) != Z_OK) {
        free( uncomp );
        return false;
    }
    for ( size_t i=0; i<strm.total_out; ++i ) {
        uncompressedBytes += uncomp[ i ];
    }
    free( uncomp );
    return true ;
}

/** Compress a STL string using zlib with given compression level and return
 * the binary data. */
std::string compress_string(const std::string& str, int compressionlevel = Z_BEST_COMPRESSION)
{
    z_stream zs;                        // z_stream is zlib's control structure
    memset(&zs, 0, sizeof(zs));
    if (deflateInit(&zs, compressionlevel) != Z_OK)
        throw(std::runtime_error("deflateInit failed while compressing."));
    zs.next_in = (Bytef*)str.data();
    zs.avail_in = str.size();           // set the z_stream's input
    int ret;
    char outbuffer[32768];
    std::string outstring;
    // retrieve the compressed bytes blockwise
    do {
        zs.next_out = reinterpret_cast<Bytef*>(outbuffer);
        zs.avail_out = sizeof(outbuffer);
        ret = deflate(&zs, Z_FINISH);
        if (outstring.size() < zs.total_out) {
            // append the block to the output string
            outstring.append(outbuffer,zs.total_out - outstring.size());
        }
    }
    while (ret == Z_OK);
    deflateEnd(&zs);
    if (ret != Z_STREAM_END) {          // an error occurred that was not EOF
        std::ostringstream oss;
        oss << "Exception during zlib compression: (" << ret << ") " << zs.msg;
        throw(std::runtime_error(oss.str()));
    }
    return outstring;
}

/* Reads a file into memory. */
bool loadBinaryFile( const std::string& filename, std::string& contents ) {
    // Open the gzip file in binary mode
    FILE* f = fopen( filename.c_str(), "rb" );
    if ( f == NULL )
        return false ;
    // Clear existing bytes in output vector
    contents.clear();
    // Read all the bytes in the file
    int c = fgetc( f );
    while ( c != EOF ) {
        contents +=  (char) c ;
        c = fgetc( f );
    }
    fclose (f);
    return true ;
}

int main(int argc, char *argv[]) {
    // Read the gzip file data into memory
    std::string fileData ;
    if ( !loadBinaryFile( "myfilein.gz", fileData ) ) {
        printf( "Error loading input file." );
        return 0 ;
    }
    // Uncompress the file data
    std::string data ;
    if ( !gzipInflate( fileData, data ) ) {
        printf( "Error decompressing file." );  
        return 0 ;  
    }  
    // Print the data  
    printf( "Data: "" );  
    for ( size_t i=0; i<data.size(); ++i ) {  
        printf( "%c", data[i] );
    }  
    printf ( ""n" );

    std::string outy;
    // Compress the file data
    outy = compress_string(data, 0);
    //Write the gzipped data to a file.
    FILE *handleWrite=fopen("myfileout.gz","wb");
    fwrite(outy,sizeof(outy),1,handleWrite);
    fclose(handleWrite);
    return 0;  
}

std::string不能被强制转换为void* (fwrite所期望的)。

试题:

  fwrite(outy.data(),outy.size(),1,handleWrite);

虽然我不确定是否存储二进制数据在std::string是一个好主意。