摘要
如何在C++中使用libarchive编写zip文件,以便路径名是UTF-8编码的?使用UTF-8路径名时,使用OS X/Linux/Windows 8/7-Zip/WinZip时,将正确解码特殊字符.
细节
我正在尝试使用libarchive编写zip存档,在Windows上使用Visual C++ 2013进行编译.
我希望能够将带有非ASCII字符的文件(例如äöü.txt)添加到zip存档中.
在libarchive中有四个函数来设置pathname标头:
void archive_entry_set_pathname(struct archive_entry *, const char *);
void archive_entry_copy_pathname(struct archive_entry *, const char *);
void archive_entry_copy_pathname_w(struct archive_entry *, const wchar_t *);
int archive_entry_update_pathname_utf8(struct archive_entry *, const char *);
Run Code Online (Sandbox Code Playgroud)
不幸的是,它们似乎都没有用.
特别是,我试过:
const char* myUtf8Str = ...
archive_entry_update_pathname_utf8(entry, myUtf8Str);
// this sounded like the most straightforward solution
Run Code Online (Sandbox Code Playgroud)
和
const wchar_t* myUtf16Str = ...
archive_entry_copy_pathname_w(entry, myUtf16Str);
// UTF-16 encoded strings seem to be the default on Windows
Run Code Online (Sandbox Code Playgroud)
在这两种情况下,生成的zip存档都不会在Windows资源管理器和7-Zip中正确显示文件名.
我确信我的输入字符串编码正确,因为我从Qt QString实例转换它们在我的代码的其他部分非常有效:
const char* …Run Code Online (Sandbox Code Playgroud) tar.gz我正在使用Libarchive::Read模块获取文件的文件列表。当 tarball 文件名中包含 UTF-8 字符时,我收到由 libarchive C 库生成的错误:
Pathname can't be converted from UTF-8 to current locale.
in block at /Users/steve/.rakubrew/versions/moar-2022.12/share/perl6/site/sources/42AF7739DF41B2DA0C4BF2069157E2EF165CE93E (Libarchive::Read) line 228
这里的 Raku 代码引发错误:
my $r := Libarchive::Read.new($newest_file);
my $needs_update = False;
for $r -> $entry { # WARNING THROWN HERE for each file in tarball listing
$entry.pathname;
$needs_update = True if $entry.is-file && $entry.pathname && $entry.pathname ~~ / ( \.t || \.pm || \.pm6 ) $ / ;
last if $needs_update;
}
Run Code Online (Sandbox Code Playgroud)
我在Mac上。该 …
我正在尝试使用 libarchive 在 Windows 上创建压缩存档,但目前它无法正常工作。我可以创建 zip 或 pax_restricted(tar) 存档而无需压缩,没有任何问题。
为了添加压缩,我尝试了以下一些组合:
archive_write_set_compression_lzip(lWriteArchive);
archive_write_add_filter_lzip(lWriteArchive);
archive_write_set_compression_gzip(lWriteArchive);
archive_write_add_filter_gzip(lWriteArchive);
archive_write_set_format_zip(lWriteArchive);
archive_write_set_format_pax_restricted(lWriteArchive);
Run Code Online (Sandbox Code Playgroud)
我主要尝试使用 zip 格式的 lzip 压缩和 pax_restricted 格式的 gzip 压缩。
首先,我不确定是否应该使用 archive_write_set_compression_* 或 archive_write_add_filter_*。
当我尝试添加 lzip 压缩并进入该函数时,我看到它返回 ARCHIVE_FATAL 并带有错误消息“此平台不支持 lzma 压缩”。
当我尝试添加 gzip 压缩并进入该函数时,我看到它返回 ARCHIVE_WARN 并带有错误消息“使用外部 gzip 程序”。如果我让该过程继续进行,则生成的存档的大小为零。
我感觉在 UNIX 系统上有 libarchive 用于压缩的 lzma 和 gzip 系统库,而这些在 Windows 上不可用。
我使用最新的稳定版本构建了 libarchive,按照使用 CMake 等的说明进行操作。我没有注意到 CMake 配置中有任何错误,例如缺少 lzma 或 gzip。
谢谢你的帮助。
我正在尝试让 libarchive 模块在 Windows 上的 python 3.4 中工作。我已经使用 pip 安装了 libarchive-c 并且一切正常,但是每当我尝试将其导入到我的代码中甚至单独运行它时,我都会收到错误:
OSError: [WinError 126] The specified module could not be found
Run Code Online (Sandbox Code Playgroud)
这来自 ffi.py,代码如下:
libarchive_path = os.environ.get('LIBARCHIVE') or find_library('archive')
libarchive = ctypes.cdll.LoadLibrary(libarchive_path)
Run Code Online (Sandbox Code Playgroud)
我以前从未使用过 ctypes,但如果我理解正确的话,它正在寻找外部 DLL。因此找到并安装了http://gnuwin32.sourceforge.net/packages/libarchive.htm我也将 C:\Program Files (x86)\GnuWin32\bin 添加到环境变量中的 %PATH% 但它仍然无法加载模块。因为它没有给我名称,所以我不确定它正在寻找什么模块。我缺少什么?
我以前从未使用过 LibArchive,并且尝试使用它来创建目录的 .tar 存档,因为它安装在我的远程计算实例上。
LibArchive 有一个示例,说明如何从平面文件列表创建存档(如下所示)。但我找不到任何有关如何从目录路径实际创建存档的示例。在同一网站的“Extract”示例中,似乎所有内容都包含在“archive_entry”结构中,但似乎没有 Create 的对应项。
void
write_archive(const char *outname, const char **filename)
{
struct archive *a;
struct archive_entry *entry;
struct stat st;
char buff[8192];
int len;
int fd;
a = archive_write_new();
archive_write_add_filter_gzip(a);
archive_write_set_format_pax_restricted(a); // Note 1
archive_write_open_filename(a, outname);
while (*filename) {
stat(*filename, &st);
entry = archive_entry_new(); // Note 2
archive_entry_set_pathname(entry, *filename);
archive_entry_set_size(entry, st.st_size); // Note 3
archive_entry_set_filetype(entry, AE_IFREG);
archive_entry_set_perm(entry, 0644);
archive_write_header(a, entry);
fd = open(*filename, O_RDONLY);
len = read(fd, buff, sizeof(buff));
while ( len > …Run Code Online (Sandbox Code Playgroud) $ condaconda 更新后,即使将解算器设置为经典(使用conda config --set solver classic) ,我在运行后也会收到以下错误:
Error while loading conda entry point: conda-libmamba-solver (libarchive.so.19: cannot open shared object file: No such file or directory)
Run Code Online (Sandbox Code Playgroud)
我有康达23.11.0。
在 Github 上有一个问题https://github.com/conda/conda-libmamba-solver/issues/283,其中他们提到如果libarchive和libmamba来自同一频道,则应该解决。
但是当我libarchive使用频道重新安装时main,它不会更新。
有谁知道如何解决这个问题?我不想从头开始重新安装 Conda。
网上类似的链接不能解决问题:
我为我的 xcode 项目使用“libarchive”,但出现以下错误
if (bytes_read < mine->block_size && ferror(mine->f)) {
archive_set_error(a, errno, "Error reading file");
}
Run Code Online (Sandbox Code Playgroud)
使用未声明的标识符 'errno'
if (mine == NULL || b == NULL) {
archive_set_error(a, ENOMEM, "No memory");
free(mine);
free(b);
return (ARCHIVE_FATAL);
}
Run Code Online (Sandbox Code Playgroud)
使用未声明的标识符“ENOMEM”
if (format_number(archive_entry_uid(entry), h + USTAR_uid_offset, USTAR_uid_size, USTAR_uid_max_size, strict)) {
archive_set_error(&a->archive, ERANGE, "Numeric user ID too large");
ret = ARCHIVE_FAILED;
}
Run Code Online (Sandbox Code Playgroud)
使用未声明的标识符“ERANGE”
write_nulls(struct archive_write *a, size_t padding)
{
int ret;
size_t to_write;
while (padding > 0) {
to_write = padding < a->null_length ? padding …Run Code Online (Sandbox Code Playgroud)