2016-07-29 2 views
0

У меня есть zip-файл, созданный с помощью другого приложения (написанного на Java), который сжимает файлы с использованием метода deflate в один zip-файл, я проверил, что информация типа «последний измененный» не была изменена до текущей дата, а при распаковке с помощью менеджера архивов по умолчанию Ubuntu он остается нетронутым.Unzipping с libzip теряет метаданные файла

Однако использование libzip для распаковки теряет эти данные. Есть ли способ избежать этого поведения или другой библиотеки, которая гарантирует сохранение метаданных?

код Декомпрессия:

void decompress_zip(const std::string& zip, const std::string& out_dir, std::function<void(const std::string&)> fileListener) { 
    std::string finput = zip; 
    std::string foutput = out_dir; 

    if(!boost::filesystem::create_directories(foutput) && !fileExists(foutput)) 
     throw "Failed to create directory for unzipping"; 

    foutput += "/tmp.zip"; 
    if (rename(finput.c_str(), foutput.c_str())) 
     throw "Failed to move zip to new dir"; 
    finput = foutput; 

    struct zip *za; 
    struct zip_file *zf; 
    struct zip_stat sb; 
    char buf[100]; 
    int err; 
    int i, len; 
    int fd; 
    long long sum; 

    if ((za = zip_open(finput.c_str(), 0, &err)) == NULL) { 
     zip_error_to_str(buf, sizeof(buf), err, errno); 
     throw "can't open zip! (" + finput + ")"; 
    } 

    for (i = 0; i < zip_get_num_entries(za, 0); i++) { 
     if (zip_stat_index(za, i, 0, &sb) == 0) { 
      len = strlen(sb.name); 

      if (sb.name[len - 1] == '/') { 
       safe_create_dir(sb.name); 
      } else { 
       zf = zip_fopen_index(za, i, 0); 
       if (!zf) { 
        throw "failed to open file in zip! Probably corrupted!!!"; 
       } 

       std::string cFile = out_dir + "/" + std::string(sb.name); 
       fd = open(cFile.c_str(), O_RDWR | O_TRUNC | O_CREAT, 0644); 
       if (fd < 0) { 
        throw "failed to create output file!"; 
       } 

       sum = 0; 
       while (sum != sb.size) { 
        len = zip_fread(zf, buf, 100); 
        if (len < 0) { 
         throw "failed to read file in zip!"; 
        } 
        write(fd, buf, len); 
        sum += len; 
       } 
       close(fd); 
       zip_fclose(zf); 

       fileListener(cFile); 
      } 
     } 
    } 

    if (zip_close(za) == -1) { 
     throw "Failed to close zip archive! " + finput; 
    } 

    if (std::remove(foutput.c_str())) 
     throw "Failed to remove temporary zip file! " + foutput; 
} 

ответ

0

Я думаю libzip хранит только данные, а не метаданных. Вы несете ответственность за хранение метаданных отдельно, если это необходимо.

Другими словами, это особенность приложения менеджера архива, а не libzip.

+0

Поскольку нет других ответов, и я провел целый день, исследуя, я боюсь, что вы правы и пометьте свой ответ как правильный. –

Смежные вопросы