Created
December 21, 2018 16:00
-
-
Save riordant/0fd270560bd2101504c8b868033fc9d9 to your computer and use it in GitHub Desktop.
Clean ZIP file creation using minizip in C++
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
(Extension of the main answer for the question here - https://stackoverflow.com/questions/11370908/how-do-i-use-minizip-on-zlib) | |
* Creates a ZIP file - | |
after specifying an absolute path to a "root" directory, all filepaths derived from this path are stored in the ZIP file, | |
with only files and their paths from the root preserved. | |
eg. root path: /a/b/c/d/ | |
filepaths(from root path): e/f.txt | |
g.dat | |
paths to folders (again, from a root) can be provided - in this case the method derives all sub-files and adds to "filePaths". | |
eg. folder path: h/i | |
derives files: h/i/j.exe | |
h/i/k.o | |
h/i/l/m.jpeg | |
Breaking up the root and derived paths allows for easy unzipping from the same directory - the layout is preserved. | |
*/ | |
bool CreateZipFile (std::string rootPath, std::vector<string> folderPaths, vector<string> filePaths, std::string destinationPath) | |
{ | |
zipFile zf = zipOpen(destinationPath.c_str(), APPEND_STATUS_CREATE); | |
if (zf == NULL) | |
return 1; | |
BOOST_FOREACH(std::string folderPath, folderPaths){ | |
std::string fullFolderPath = rootPath + folderPath; | |
for (const auto & entry : boost::filesystem::directory_iterator(fullFolderPath)){ | |
std::string fullFolderFilePath = entry.path().string(); | |
std::string folderFilePath = fullFolderFilePath.substr(rootPath.length()); | |
filePaths.push_back(folderFilePath); | |
} | |
} | |
bool failed = false; | |
BOOST_FOREACH(string filePath, filePaths) | |
{ | |
if(failed){ | |
break; | |
} | |
std::string fullPath = rootPath + filePath; | |
std::fstream file(fullPath.c_str(), std::ios::binary | std::ios::in); | |
if (file.is_open()) | |
{ | |
file.seekg(0, std::ios::end); | |
long size = file.tellg(); | |
file.seekg(0, std::ios::beg); | |
std::vector<char> buffer(size); | |
if (size == 0 || file.read(&buffer[0], size)){ | |
zip_fileinfo zfi = { 0 }; | |
if (ZIP_OK == zipOpenNewFileInZip(zf, filePath.c_str(), &zfi, NULL, 0, NULL, 0, NULL, Z_DEFLATED, Z_DEFAULT_COMPRESSION)) | |
{ | |
if (ZIP_OK != zipWriteInFileInZip(zf, size == 0 ? "" : &buffer[0], size)){ | |
failed = true; | |
} | |
if (ZIP_OK != zipCloseFileInZip(zf)){ | |
failed = true; | |
} | |
file.close(); | |
continue; | |
} | |
} | |
file.close(); | |
} | |
failed = true; | |
} | |
zipClose(zf, NULL); | |
if (failed){ | |
return false; | |
} | |
return true; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment