0

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?

6
  • Side note: "zip_filename.zip" is a string literal, a const array of char of exactly the right size. It implicitly converts to a const char *, so you can discard const char* zipFileName = "zip_filename.zip"; and directly use it. Eg: if (unzipFile("zip_filename.zip", "extracted_file.csv")) Commented Mar 28, 2024 at 16:48
  • 1
    Note "zip_filename.zip" is also a relative path and thus depends on the Working Directory being exactly where you put the zip file. Make sure you know where the working directory is because we could have a Stack Exchange site just for the questions where the asker thought the working directory was somewhere it wasn't. So the first thing to do is make sure the program is looking in the right spot for the file. Commented Mar 28, 2024 at 16:56
  • 1
    Suggestion: step through the program with a debugger and pinpoint exactly where it fails. Most likely you'll get an error code in ret that'll give you a hint about what happened you can add to the question to make it easier to find for the next person with a similar problem. Commented Mar 28, 2024 at 17:03
  • 1
    You are asking about the Failed to unzip file error, but there are other messages also being logged when a specific error condition occurs. Are you seeing any of those messages? Do note that there is no error handling being done on the inFile.read() and outFile.write() calls, and no log message being reported if inflate() fails, so you should correct those issues. Commented Mar 28, 2024 at 17:22
  • 1
    As far as I understand your code you use the Gailly-Adler zlib. What you do is handling the content of the input file as a raw deflated bytestream. But if the file is in fact a zip library, it has a more complex internal data structure and plain simply inflating it can't work. So unfortunately you need to learn about the internal structure of a zip file and first find the portion within the zip file which really represents the deflated bytestream of the contained csv (the zip spec). Commented Mar 28, 2024 at 18:59

1 Answer 1

0

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.

Sign up to request clarification or add additional context in comments.

1 Comment

I've given up I did it in Pytohn. So much easier...

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.