gpt4 book ai didi

c++ - 在 libarchive 中设置 UTF-8 路径名 header

转载 作者:可可西里 更新时间:2023-11-01 18:39:04 27 4
gpt4 key购买 nike

总结

我如何在 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 中设置路径名头的函数有四个:

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 *);

不幸的是,它们似乎都不起作用。

特别是,我尝试过:

const char* myUtf8Str = ...
archive_entry_update_pathname_utf8(entry, myUtf8Str);
// this sounded like the most straightforward solution

const wchar_t* myUtf16Str = ...
archive_entry_copy_pathname_w(entry, myUtf16Str);
// UTF-16 encoded strings seem to be the default on Windows

在这两种情况下,生成的 zip 存档都不会在 Windows 资源管理器和 7-Zip 中正确显示文件名。

我确定我的输入字符串编码正确,因为我将它们从 Qt QString 实例转换而来,这些实例在我的代码的其他部分工作得很好:

const char* myUtf8Str = filename.toUtf8().constData();
const wchar_t* myUtf16Str = filename.toStdWString().c_str();

例如,这甚至适用于在创建 zip 文件时对 libarchive 的另一个调用:

archive_write_open_filename_w(archive, zipFile.toStdWString().c_str());
// creates a zip archive file where the non-ASCII
// chars are encoded correctly, e.g. äöü.zip

我还尝试按照 this example 的建议更改 libarchive 的选项:

archive_write_set_options(a, "hdrcharset=UTF-8");

但是这个调用失败了,所以我假设我必须设置一些其他选项,但是我的想法已经用完了......

更新 2

我已经阅读了更多关于 zip 格式的资料。它允许以 UTF-8 编写文件名,这样 OS X/Linux/Windows 8/7-Zip/WinZip 将始终正确解码它们,参见例如here .

这就是我想使用 libarchive 实现的目标,即我想将我的 UTF-8 编码的 pathname 传递给它,并将其存储在 zip 文件中而不进行任何转换。

我添加了“设置语言环境”方法作为(不令人满意的)答案。

最佳答案

这是一种解决方法,它将使用系统的区域设置存储路径名,即生成的 zip 文件可以在同一系统上正确解码,但不可移植。

这并不令人满意,我发布它只是为了表明它不是我想要的。

将全局区域设置为 "" 作为 explained here :

std::locale::global(std::locale(""));

然后回读:

std::locale loc;
std::cout << loc.name() << std::endl;
// output: English_United States.1252
// may of course be different depending on system settings

然后使用 archive_entry_update_pathname_utf8 设置 pathname

zip 文件现在包含使用 Windows-1252 编码的文件名,因此我的 Windows 可以读取它们,但它们在例如Linux.

future

有一个libarchive issue对于 UTF-8 文件名。整个故事相当复杂,但听起来他们可能会在 libarchive 4.0 中添加更好的 UTF-8 支持。

关于c++ - 在 libarchive 中设置 UTF-8 路径名 header ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27268016/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com