c – 在libarchive中设置UTF-8路径名头

摘要

如何在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 *);

不幸的是,它们似乎都没有用.

特别是,我试过:

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

我也试图改变libarchive的选项,如this example所示:

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

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

更新2

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

这是我想用libarchive实现的,即我想将它传递给我的UTF-8编码路径名并将其存储在zip文件中而不进行任何转换.

添加了“set locale”方法作为(不满意的)答案.

解决方法

这是一种使用系统的语言环境设置存储路径名称解决方法,即生成的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设置路径名.

zip文件现在包含用Windows-1252编码的文件名,因此我的Windows可以读取它们,但它们在例如垃圾邮件显示垃圾邮件. Linux操作系统.

未来

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

相关文章

对象的传值与返回说起函数,就不免要谈谈函数的参数和返回值...
从实现装饰者模式中思考C++指针和引用的选择最近在看...
关于vtordisp知多少?我相信不少人看到这篇文章,多半是来自...
那些陌生的C++关键字学过程序语言的人相信对关键字并...
命令行下的树形打印最近在处理代码分析问题时,需要将代码的...
虚函数与虚继承寻踪封装、继承、多态是面向对象语言的三大特...