I have uploaded a zip file compressed with 7-zip option add to .zip containing only a file with the name text.txt into GitHub, how I could read the content of the file text.txt without writing it to disk?
I'm downloading the zip to memory using curl:
#include <curl/curl.h>
static size_t WriteMemoryCallback(void* contents, size_t size, size_t nmemb,
void* userp) {
size_t realsize = size * nmemb;
auto& mem = *static_cast<std::string*>(userp);
mem.append(static_cast<char*>(contents), realsize);
return realsize;
}
std::string Download(const std::string& url)
{
CURL* curl_handle;
CURLcode res;
std::string chunk;
curl_global_init(CURL_GLOBAL_ALL);
curl_handle = curl_easy_init();
curl_easy_setopt(curl_handle, CURLOPT_URL, url.c_str());
curl_easy_setopt(curl_handle, CURLOPT_WRITEFUNCTION, WriteMemoryCallback);
curl_easy_setopt(curl_handle, CURLOPT_WRITEDATA, &chunk);
curl_easy_setopt(curl_handle, CURLOPT_USERAGENT, "libcurl-agent/1.0");
// added options that may be required
curl_easy_setopt(curl_handle, CURLOPT_FOLLOWLOCATION, 1L); // redirects
curl_easy_setopt(curl_handle, CURLOPT_HTTPPROXYTUNNEL, 1L); // corp. proxies etc.
curl_easy_setopt(curl_handle, CURLOPT_VERBOSE, 1L); // we want it all
// curl_easy_setopt(curl_handle, CURLOPT_REDIR_PROTOCOLS, CURLPROTO_HTTP | CURLPROTO_HTTPS);
res = curl_easy_perform(curl_handle);
if(res != CURLE_OK) {
std::cerr << "curl_easy_perform() failed: " << curl_easy_strerror(res) << '\n';
} else {
std::cout << chunk.size() << " bytes retrieved\n";
}
curl_easy_cleanup(curl_handle);
curl_global_cleanup();
return chunk;
}
int _tmain(int argc, _TCHAR* argv[])
{
std::string link = "https://github.com/.../main/text.zip";
auto data = Download(link);
}
While searching for a lib capable of uncompressing the zip on memory, I found this one: libzip (any lib is welcome).
Searching for examples I found this answer, however he's loading a zip from disk to memory and reading it content.
How I could read the zip downloaded with curl that is on the string data?
When I visualize the content of data in the debugger it shows PK, I tried passing it to zip *z, but z returns null
//Open the ZIP archive
int err = 0;
zip *z = zip_open(data.c_str(), 0, &err);
//Search for the file of given name
const char *name = "text.txt";
struct zip_stat st;
zip_stat_init(&st);
zip_stat(z, name, 0, &st);
//Alloc memory for its uncompressed contents
char *contents = new char[st.size];
//Read the compressed file
zip_file *f = zip_fopen(z, name, 0);
zip_fread(f, contents, st.size);
zip_fclose(f);
I'm ignoring everything about curl in the question because we've verified that you've got the
zipfile stored in memory correctly.Since you have the whole zip file stored in memory, you need to create a
zip_sourcefromchunk.data()and open the archive using thatzip_source- and then open the individual files in the archive.Here's how (without error checking - you need to add that):