У меня проблемы с libarchive
версия 3.3.2. Я написал программу для чтения выбранных записей в архивах 7z, которые выглядят так:
file.7z
|__ file.xml
|__ file.fog
|__ file_1.fog
Однако программа не смогла прочитать file_1.fog
для большинства моих архивов и не удалось прочитать file.fog
для некоторых. Я пытался использовать archive_error_string()
чтобы увидеть, что происходит, и ошибки были либо corrupted archive
или же truncated RAR archive
или же Decompressing internal error
,
Вот архив образец и код неисправности:
void list_archive(string name) {
struct archive *a;
struct archive_entry *entry;
// create new archive struct for the file
a = archive_read_new();
archive_read_support_filter_all(a);
archive_read_support_format_all(a);
// open 7z file
int r = archive_read_open_filename(a, name.c_str(), 1024);
if (r != ARCHIVE_OK) {
cout << "cannot read file: " << name << endl;
cout << "read error: " << archive_error_string(a) << endl;
}
// looping through entries
for (;;) {
int status = archive_read_next_header(a, &entry);
// if there's no more header
if (status != ARCHIVE_OK) break;
// print some status messages to stdout
string pathname(archive_entry_pathname(entry));
cout << "working on: " << pathname << endl;
size_t entry_size = archive_entry_size(entry);
// load the entry's content
char * content;
content = (char*)malloc(entry_size);
r = archive_read_data(a, content, entry_size);
// check if archive_read_data was successful
if (r > 0) {
cout << "read " << r << " of " << entry_size << " bytes successfully\n";
// we are interested in .fog file only
if (pathname.back() == 'g') {
// do something with the .fog file
}
}
else // usually the error happens here
if (archive_errno(a) != ARCHIVE_OK) cout << "read error: " << archive_error_string(a) << endl;// free the content and clear the entry
archive_read_data_skip(a);
free(content);
archive_entry_clear(entry);
cout << "-----" << endl;
}
// we are done with the current archive, free it
r = archive_read_free(a);
if (r != ARCHIVE_OK) {
cout << "Failed to free archive object. Error: " << archive_error_string(a) << endl;
exit(1);
}
}
Я нашел нарушителя спокойствия и отвечу здесь, если у будущих пользователей возникнут такие же проблемы.
int r = archive_read_open_filename(a, name.c_str(), 1024);
По-видимому 1024
слишком мал для размера буфера. Я увеличил это до 102400
и смог прочитать / извлечь все мои архивы.
Других решений пока нет …