0

I'm tring create zip file with libzip library.

list<string> ListOfFiles; 

ListOfFiles.push_back("file1");
ListOfFiles.push_back("file2");
ListOfFiles.push_back("file3");
... 

createZip(const char* destination)
{
 int err;

 zip *archive = zip_open(destination, ZIP_CREATE, &err);
 cout << "1. " << zip_strerror(archive) << endl;

    for (list<string>::iterator iter = ListOfFiles.begin(), end = ListOfFiles.end(); iter != end; iter++)
    {
        zip_source *source = zip_source_file(archive,iter->c_str(),0,0);             
        cout << "2. " << zip_strerror(archive) << endl;

        index = zip_file_add(archive, iter->c_str(), source, ZIP_FL_OVERWRITE);
        cout << "3. " << zip_strerror(archive) << endl; 
   }

  zip_close(archive);
  cout << "4. " << zip_strerror(archive) << endl;
}

output:

  1. No error

  2. No error

  3. Invalid argument ...

  4. Read error: No such file or directory

When I tried create zip, error value return "Invalid argument" after i tried added file to zip.

gomess
  • 83
  • 1
  • 8
  • https://www.mankier.com/3/zip_file_add says that invalid argument means "source or name are NULL". Can you double-check that `source` isn't `NULL` in Step 2? Otherwise, your code looks fine to me, based on reading libzip's documentation. – Rob Starling Apr 19 '17 at 21:23
  • Also, in Step 1, check that `err` isn't set and that `archive` is not `NULL` before asking `zip_strerror` to look at it, since it could be NULL. – Rob Starling Apr 19 '17 at 21:23
  • The last error is normal if one of the files doesn't exist, as far as I can tell. – Rob Starling Apr 19 '17 at 21:29
  • Archive is OK, When i tried put filename directly as argument for zip_source_file instead of iterator, everything worked fine. – gomess Apr 20 '17 at 07:08
  • I will try check `source` for NULL , later when i get home – gomess Apr 20 '17 at 07:13
  • added check for `archive` and `source` are not NULL. What i found, only one problem is in `zip_file_add` in fname, when I put directly string filename as argument everything is OK. Can be difference between `iter->c_str()` and "filename"? – gomess Apr 20 '17 at 17:25
  • oh no. i have an idea, but it's worrisome. Could it be the case that one or both of those functions (`zip_source_file` and `zip_file_add`) does something irresponsible with the pointer, like hanging on to it, rather than copying its contents? This is leaky, but for the sake of experimentation, try a) wrapping the params in `strdup` (e.g. `zip_source_file(archive, strdup(iter->c_str()), 0, 0)`) and b) printing the string _after_ the calls to see if it's still there (e.g. `cout << "3b. " << iter->c_str() << endl;`) – Rob Starling Apr 20 '17 at 17:37
  • without change, output is same and new `cout` print what should print – gomess Apr 21 '17 at 07:37
  • Do you have the same problem if you replace `ZIP_FL_OVERWRITE` with `ZIP_FL_OVERWRITE | ZIP_FL_ENC_UTF_8`? – RyanCu Jun 06 '19 at 01:27

1 Answers1

0

For further help here is my code that worked for me.

int main() {

    int err = 0;
    ifstream fs, fs1;
    fs.open("my_test.txt", std::ios::binary);
    fs1.open("f 2.pdf", std::ios::binary);
    std::string content((std::istreambuf_iterator<char>(fs)), (std::istreambuf_iterator<char>()));
    std::string content1((std::istreambuf_iterator<char>(fs1)), (std::istreambuf_iterator<char>()));

    zip* z = zip_open("foo.zip", ZIP_CREATE, &err);
    zip_source_t* zs;

    zs = zip_source_buffer(z, content.c_str(), content.length(), 0);

    zip_file_add(z, "test.txt", zs, ZIP_FL_OVERWRITE | ZIP_FL_ENC_UTF_8);
    zs = zip_source_buffer(z, content1.c_str(), content1.length(), 0);
    zip_file_add(z, "test.pdf", zs, ZIP_FL_OVERWRITE | ZIP_FL_ENC_UTF_8);

    zip_close(z);}

i opened 2 files (one txt and one pdf) in binary mode and read the entire files. I have store its data to two string contents. Next i have created the zip file (foo.zip), Next step is to create the source buffer. first argument is the zip file second is the content the third is the length of the content to be written. finally we add the buffer inside the zip. BE CAREFUL the zip_file_add creates new file with the name provided (my_test.txt-> text.txt and f 2.pdf -> test.pdf)

Anagnostou John
  • 498
  • 5
  • 14