鸿蒙-ArkTS和Native之间的交互使用11使用libarchive创建getExtractFi

仿佛云烟
发布于 2025-6-28 16:52
浏览
0收藏
前言:

鸿蒙-ArkTS和Native之间的交互使用11使用libarchive创建getExtractFi-鸿蒙开发者社区


使用 ​​libarchive​​ 库提取压缩包内的单个指定文件,需通过遍历条目、匹配文件名并提取数据实现。


  1. 初始化并配置libarchive读取对象。
  2. 打开压缩包文件。
  3. 遍历每个条目,检查路径名是否匹配目标文件。
  4. 如果找到,读取数据并写入输出文件。
  5. 处理未找到的情况,释放资源。


初始化读取对象并配置格式


创建 ​​libarchive​​ 读取对象,启用支持的压缩格式和过滤器:


#include 
#include 

struct archive *a = archive_read_new();
archive_read_support_filter_all(a);  // 支持所有解压过滤器
archive_read_support_format_all(a);  // 支持所有归档格式


打开压缩包文件


通过 ​​archive_read_open_filename​​ 打开目标文件,并检查是否成功:


if (archive_read_open_filename(a, "example.zip", 10240) != ARCHIVE_OK) {
    fprintf(stderr, "Error: %s\n", archive_error_string(a));
    return;
}


遍历条目并匹配目标文件


循环读取每个条目,检查文件名是否与目标匹配:


const char *target_file = "path/to/file.txt";  // 目标文件路径
struct archive_entry *entry;
int found = 0;

while (archive_read_next_header(a, &entry) == ARCHIVE_OK) {
    const char *pathname = archive_entry_pathname(entry);
    
    // 匹配文件名(区分大小写)
    if (strcmp(pathname, target_file) == 0) {
        found = 1;
        break;
    }
    archive_read_data_skip(a);  // 跳过非目标文件的数据
}


提取文件数据


若找到目标文件,将其内容写入本地文件:


if (found) {
    FILE *out = fopen("output.txt", "wb");
    if (!out) {
        perror("Failed to open output file");
        return;
    }

    const void *buff;
    size_t size;
    la_int64_t offset;

    // 逐块读取数据并写入文件
    while (archive_read_data_block(a, &buff, &size, &offset) == ARCHIVE_OK) {
        fwrite(buff, 1, size, out);
    }
    fclose(out);
    printf("File extracted successfully.\n");
} else {
    printf("File not found in the archive.\n");
}


错误处理与资源释放


确保释放资源并处理潜在错误:


if (archive_errno(a) != 0) {
    fprintf(stderr, "Error: %s\n", archive_error_string(a));
}
archive_read_free(a);  // 释放读取对象


完整示例代码


#include 
#include 
#include 
#include 

void getExtractFile(const char *archive_path, const char *target_path) {
    struct archive *a = archive_read_new();
    archive_read_support_filter_all(a);
    archive_read_support_format_all(a);

    if (archive_read_open_filename(a, archive_path, 10240) != ARCHIVE_OK) {
        fprintf(stderr, "Error opening archive: %s\n", archive_error_string(a));
        return;
    }

    struct archive_entry *entry;
    int found = 0;

    while (archive_read_next_header(a, &entry) == ARCHIVE_OK) {
        const char *pathname = archive_entry_pathname(entry);
        if (strcmp(pathname, target_path) == 0) {
            found = 1;
            break;
        }
        archive_read_data_skip(a);
    }

    if (found) {
        FILE *out = fopen("output.bin", "wb");
        if (!out) {
            perror("Failed to create output file");
            archive_read_free(a);
            return;
        }

        const void *buff;
        size_t size;
        la_int64_t offset;

        while (archive_read_data_block(a, &buff, &size, &offset) == ARCHIVE_OK) {
            fwrite(buff, 1, size, out);
        }
        fclose(out);
        printf("Extracted: %s\n", target_path);
    } else {
        printf("File '%s' not found.\n", target_path);
    }

    archive_read_free(a);
}


说明:


  1. 路径匹配逻辑
  • 需确保​​target_file​​ 的路径与压缩包内条目路径完全一致(包括大小写和相对路径格式)。
  • 若需模糊匹配(如仅匹配文件名),可使用​​strstr​​ 或正则表达式。
  1. 数据提取优化
  • 使用​​archive_read_data_block​​ 逐块读取数据,避免内存溢出。
  • 若需直接获取数据到内存,可替换​​fwrite​​ 为自定义缓冲逻辑。
  1. 格式兼容性
  • 通过​​archive_read_support_format_all​​,支持 ZIP、TAR、7z 等常见格式。


分类
收藏
回复
举报
回复
    相关推荐