C++多文件压缩为Zip求助:tar转Zip遇问题,需C++实现方案
Hey there! I totally get where you're coming from—minizip can feel pretty clunky when you're just starting out with C++ compression. Let's walk through a straightforward, beginner-friendly way to compress multiple files into a .zip using minizip, with clear code and explanations.
First, make sure you have the minizip headers (like zip.h) and library files installed. Most systems let you grab this via package managers (e.g., libminizip-dev on Debian/Ubuntu), or you can build it from the zlib source if needed.
Here's a complete, commented example that takes a list of files and packs them into a zip. I've wrapped the messy bits into a helper function so you don't have to deal with low-level details every time:
#include <iostream> #include <fstream> #include <string> #include <vector> #include <ctime> // Include minizip's core header #include "zip.h" // Helper function: Read a local file and add it to the zip bool add_file_to_zip(zipFile zip_handle, const std::string& local_file_path, const std::string& zip_internal_path) { // Open the local file in binary mode std::ifstream input_file(local_file_path, std::ios::binary); if (!input_file.is_open()) { std::cerr << "Oops! Couldn't open file: " << local_file_path << std::endl; return false; } // Get the file size input_file.seekg(0, std::ios::end); const std::streampos file_size = input_file.tellg(); input_file.seekg(0, std::ios::beg); // Allocate buffer to hold the file content char* file_buffer = new char[static_cast<size_t>(file_size)]; input_file.read(file_buffer, file_size); // Set up metadata for the zip entry (like timestamp) zip_fileinfo zip_entry_info = {0}; const time_t now = time(nullptr); const tm* local_time = localtime(&now); zip_entry_info.tmz_date.tm_sec = local_time->tm_sec; zip_entry_info.tmz_date.tm_min = local_time->tm_min; zip_entry_info.tmz_date.tm_hour = local_time->tm_hour; zip_entry_info.tmz_date.tm_mday = local_time->tm_mday; zip_entry_info.tmz_date.tm_mon = local_time->tm_mon; zip_entry_info.tmz_date.tm_year = local_time->tm_year; // Create a new entry in the zip const int open_result = zipOpenNewFileInZip( zip_handle, zip_internal_path.c_str(), &zip_entry_info, nullptr, 0, nullptr, 0, nullptr, Z_DEFLATED, // Use standard zip compression Z_DEFAULT_COMPRESSION // Default compression level (balanced speed/size) ); if (open_result != ZIP_OK) { std::cerr << "Failed to create entry in zip: " << zip_internal_path << std::endl; delete[] file_buffer; return false; } // Write the file content to the zip entry const int write_result = zipWriteInFileInZip(zip_handle, file_buffer, static_cast<size_t>(file_size)); if (write_result != ZIP_OK) { std::cerr << "Failed to write content to zip entry: " << zip_internal_path << std::endl; zipCloseFileInZip(zip_handle); delete[] file_buffer; return false; } // Close the zip entry const int close_result = zipCloseFileInZip(zip_handle); if (close_result != ZIP_OK) { std::cerr << "Failed to close zip entry: " << zip_internal_path << std::endl; delete[] file_buffer; return false; } delete[] file_buffer; std::cout << "Successfully added: " << local_file_path << " -> " << zip_internal_path << std::endl; return true; } int main() { // Define your output zip file name const std::string output_zip = "my_archive.zip"; // List of files to compress: {local_file_path, path_inside_zip} // You can organize files into folders inside the zip using the second string! const std::vector<std::pair<std::string, std::string>> files_to_pack = { {"document.txt", "docs/document.txt"}, {"photo.jpg", "media/photo.jpg"}, {"data.tar", "archives/data.tar"} // Your existing tar file works here too! }; // Open the zip file (create new or overwrite if exists) zipFile zip_handle = zipOpen(output_zip.c_str(), ZIP_CREATE | ZIP_TRUNCATE); if (!zip_handle) { std::cerr << "Error: Couldn't create zip file " << output_zip << std::endl; return 1; } // Add all files to the zip bool all_files_succeeded = true; for (const auto& file_pair : files_to_pack) { if (!add_file_to_zip(zip_handle, file_pair.first, file_pair.second)) { all_files_succeeded = false; } } // Close the zip file properly const int close_zip_result = zipClose(zip_handle, nullptr); if (close_zip_result != ZIP_OK) { std::cerr << "Error: Couldn't close zip file" << std::endl; return 1; } // Final status message if (all_files_succeeded) { std::cout << "\nAll files packed successfully into " << output_zip << "!" << std::endl; } else { std::cout << "\nSome files failed to pack—check the error messages above." << std::endl; } return 0; }
- On Linux/macOS, compile with:
g++ -o zip_packer zip_packer.cpp -lminizip -lz - On Windows, link against the minizip library (usually
minizip.lib) and zlib in your IDE or build script.
- The
files_to_packvector lets you set both the local file path and where it lives inside the zip (so you can create folders likedocs/ormedia/). Z_DEFLATEDis the standard zip compression algorithm—if you want no compression, useZ_STOREDinstead.- Always make sure to close files (both local and zip entries) properly to avoid corrupted archives.
内容的提问来源于stack exchange,提问作者kumar

