C++ how to unzip file

62 Views Asked by At

I found this code to unzip files:

#include <zlib.h>

#define CHUNK_SIZE 16384 // 16 KB

bool unzipFile(const char* zipFileName, const char* extractFileName) {
    // Open the input file (compressed)
    std::ifstream inFile(zipFileName, std::ios::binary);
    if (!inFile.is_open()) {
        std::cerr << "Error: Unable to open input file." << std::endl;
        return false;
    }

    // Open the output file (uncompressed)
    std::ofstream outFile(extractFileName, std::ios::binary);
    if (!outFile.is_open()) {
        std::cerr << "Error: Unable to create output file." << std::endl;
        inFile.close();
        return false;
    }

    // Initialize zlib structures
    z_stream stream;
    stream.zalloc = Z_NULL;
    stream.zfree = Z_NULL;
    stream.opaque = Z_NULL;
    stream.avail_in = 0;
    stream.next_in = Z_NULL;
    if (inflateInit(&stream) != Z_OK) {
        std::cerr << "Error: Failed to initialize zlib." << std::endl;
        inFile.close();
        outFile.close();
        return false;
    }

    // Uncompress data
    unsigned char inBuffer[CHUNK_SIZE];
    unsigned char outBuffer[CHUNK_SIZE];
    int ret;
    do {
        inFile.read(reinterpret_cast<char*>(inBuffer), CHUNK_SIZE);
        stream.avail_in = inFile.gcount();
        stream.next_in = inBuffer;
        do {
            stream.avail_out = CHUNK_SIZE;
            stream.next_out = outBuffer;
            ret = inflate(&stream, Z_NO_FLUSH);
            switch (ret) {
                case Z_NEED_DICT:
                case Z_DATA_ERROR:
                case Z_MEM_ERROR:
                    inflateEnd(&stream);
                    inFile.close();
                    outFile.close();
                    return false;
            }
            outFile.write(reinterpret_cast<char*>(outBuffer), CHUNK_SIZE - stream.avail_out);
        } while (stream.avail_out == 0);
    } while (ret != Z_STREAM_END);

    // Clean up
    inflateEnd(&stream);
    inFile.close();
    outFile.close();

    return true;
}

int main()
{
   const char* zipFileName = "zip_filename.zip";
   const char* extractFileName = "extracted_file.csv";
   if (unzipFile(zipFileName, extractFileName)) {
        std::cout << "File unzipped successfully." << std::endl;
    } else {
        std::cerr << "Failed to unzip file." << std::endl;
    }
}

But it returns false when trying it. I get "Failed to unzip file." So it comes after the // Uncompress data part, as I don;t get any other error prior to that block.

I am not sure what' wrong here, It's a classic zip file with a csv file in it. I've been stuck without any clue what's wrong. Someone knows the error please?

1

There are 1 best solutions below

1
Mark Adler On

That code will decompress a zlib stream, not a zip file. Two different things. Wherever you found that code, the function is very poorly named. It does not do what it the name claims: unzipFile.

You can look at libraries like libarchive to unzip file, or you can write your own using the zip file format specification, supported by zlib for the raw decompression of the deflate format and for CRC calculations.