Home > Net >  Locating a file by path/name in a zip using libarchive
Locating a file by path/name in a zip using libarchive

Time:11-03

I'm using libarchive in c/c to create a zip archive of files and I'm trying to find if there is a good way to find if a file name (or rather file in a path) already exists in a file.

Currently, my only way is to cycle through all the headers and compare the filenames to the one I am looking to put into the zip, based on the example code from the libarchive website:

  struct mydata *mydata;
  struct archive *a;
  struct archive_entry *entry;
  mydata = malloc(sizeof(struct mydata));
  a = archive_read_new();
  mydata->name = name;
  mydata->fd = open(mydata->name, O_RDONLY); // Include O_BINARY on Windows
  archive_read_support_compression_all(a);
  archive_read_support_format_all(a);
  archive_read_open(a, mydata, NULL, myread, myclose);
  while (archive_read_next_header(a, &entry) == ARCHIVE_OK) {
     printf("%s\n",archive_entry_pathname(entry));
  }
  archive_read_finish(a);
  free(mydata);

The printf function has been edited in my code to a comparison. Obviously this has quite a significant overhead as the zip file gets bigger and there are a large number of headers to check.

Is this the best way or am I missing something simpler?

CodePudding user response:

As libarchive's README suggests, the library is intended for handling streaming archives, rather than randomly-accessed ones. It therefore stands to reason that, in order to locate a file in the archive, you have to "roll the tape", so to speak, until you reach it.

You could cache its contents in memory, like @kiner_shah suggests, by making a single pass over the archive with a while (archive_read_next_header(my_archive, &entry) == ARCHIVE_OK) { ... } loop; then you'll have whatever data structure you like for the different directories and files.

  • Related