在UNC路径上使用libarchive提取.tar.gz?

时间:2017-04-20 10:04:35

标签: c++ c windows unc libarchive

我正在尝试使用<form />libarchive文件解压缩到当前文件夹。如果win7 64bit在虚拟机箱下运行,请测试机器。如果我在.tar.gzC:\磁盘)中执行它,它可以正常工作,但它在.vdi(来自主机的共享文件夹)上失败。基于此

E:\

错误消息我认为问题是UNC路径。是否可以使用Can't create '\\?\e:\folder\file' 处理它?<​​/ p>

这是我的代码:

libarchive

我想我可以首先使用https://stackoverflow.com/a/2324777/781743和chdir到非unc路径(如果存在),这应该有用吗?但有没有办法直接提出#include <iostream> #include <cstdio> #include <stdexcept> #include <archive.h> #include <archive_entry.h> #include "utils.h" int copy_data(struct archive * ar, struct archive * aw) { int r; size_t size; const void *buff; int64_t offset; for (;;) { r = archive_read_data_block(ar, &buff, &size, &offset); if (r == ARCHIVE_EOF) { return (ARCHIVE_OK); } else if (r < ARCHIVE_OK) { return (r); } r = archive_write_data_block(aw, buff, size, offset); if (r < ARCHIVE_OK) { std::cerr << archive_error_string(aw) << std::endl; return (r); } } } void handle_errors(archive * a, int r, const char * msg) { if (r < ARCHIVE_OK) { std::cerr << archive_error_string(a) << std::endl; } if (r < ARCHIVE_WARN) { throw std::runtime_error(msg); } }; void extract(std::string target_file_name) { struct archive * a = nullptr; struct archive * ext = nullptr; struct archive_entry * entry = nullptr; int flags, r; /* Select which attributes we want to restore. */ flags = ARCHIVE_EXTRACT_TIME; flags |= ARCHIVE_EXTRACT_UNLINK; flags |= ARCHIVE_EXTRACT_SECURE_NODOTDOT; a = archive_read_new(); if (!a) { throw std::runtime_error("Cannot archive_read_new"); } On_Scope_Exit([&] { archive_read_free(a); }); archive_read_support_format_tar(a); archive_read_support_filter_gzip(a); ext = archive_write_disk_new(); if (!ext) { throw std::runtime_error("Cannot archive_write_disk_new"); } On_Scope_Exit([&] { archive_write_close(ext); archive_write_free(ext); }); archive_write_disk_set_options(ext, flags); archive_write_disk_set_standard_lookup(ext); if ((r = archive_read_open_filename(a, target_file_name.c_str(), 10240))) { throw std::runtime_error("Cannot archive_read_open_filename"); } On_Scope_Exit([&] { archive_read_close(a); }); for (;;) { r = archive_read_next_header(a, &entry); if (r == ARCHIVE_EOF) { break; } handle_errors(a, r, "Encountered error while reading header."); r = archive_write_header(ext, entry); if (r < ARCHIVE_OK) { std::cerr << archive_error_string(ext) << std::endl; } else if (archive_entry_size(entry) > 0) { r = copy_data(a, ext); handle_errors(ext, r, "Encountered error while copy data."); } r = archive_write_finish_entry(ext); handle_errors(ext, r, "Encountered error while finishing entry."); } } int main(int, char**) { try { std::string tmp_file_name = "file.tar.gz"; extract(tmp_file_name); return 0; } catch (std::exception & e) { std::cerr << e.what() << std::endl; return 1; } } 支持libarchive路径?

1 个答案:

答案 0 :(得分:0)

这对我有用 [详细初始值为0,do_extract为1,标志设置为ARCHIVE_EXTRACT_TIME]

struct archive *a;
struct archive *ext;
struct archive_entry *entry;
int r;

a = archive_read_new();
ext = archive_write_disk_new();
archive_write_disk_set_options(ext, flags);
/*
 * Note: archive_write_disk_set_standard_lookup() is useful
 * here, but it requires library routines that can add 500k or
 * more to a static executable.
 */
archive_read_support_format_tar(a);
archive_read_support_filter_gzip(a);
/*
 * On my system, enabling other archive formats adds 20k-30k
 * each.  Enabling gzip decompression adds about 20k.
 * Enabling bzip2 is more expensive because the libbz2 library
 * isn't very well factored.
 */
if (filename != NULL && strcmp(filename, "-") == 0)
    filename = NULL;
if ((r = archive_read_open_filename(a, filename, 10240)))
    fail("archive_read_open_filename()",
        archive_error_string(a), r);
for (;;) {
    r = archive_read_next_header(a, &entry);
    if (r == ARCHIVE_EOF)
        break;
    if (r != ARCHIVE_OK)
        fail("archive_read_next_header()",
            archive_error_string(a), 1);
    if (verbose && do_extract)
        msg("x ");
    if (verbose || !do_extract)
        msg(archive_entry_pathname(entry));
    if (do_extract) {
        r = archive_write_header(ext, entry);
        if (r != ARCHIVE_OK)
            warn("archive_write_header()",
                archive_error_string(ext));
        else {
            copy_data(a, ext);
            r = archive_write_finish_entry(ext);
            if (r != ARCHIVE_OK)
                fail("archive_write_finish_entry()",
                    archive_error_string(ext), 1);
        }
    }
    if (verbose || !do_extract)
        msg("\n");
}
archive_read_close(a);
archive_read_free(a);

archive_write_close(ext);
archive_write_free(ext);
exit(0);