boost.log 使用 UTF8 文件名创建文件时出现问题

boost.log issue creating a file with a UTF8 file name

我使用boost.log根据字符串值创建多日志文件。但是当字符串是UTF8编码时,创建的文件名称不正确(像这样:è°.æ¦ç)。

BOOST_LOG_SCOPED_LOGGER_ATTR(Logger::motion_checker, "RoleName", boost::log::attributes::constant< std::string >(name))

typedef boost::log::sinks::asynchronous_sink<boost::log::sinks::text_multifile_backend> multifile_sink;
boost::shared_ptr<multifile_sink> sink(new multifile_sink);
sink->locked_backend()->set_file_name_composer(boost::log::sinks::file::as_file_name_composer(
    boost::log::expressions::stream << "./log/MotionCheck/" << boost::log::expressions::attr< std::string >("RoleName") << ".log"));
sink->set_formatter
    (
        boost::log::expressions::format("[%1%] - %2%")
        % boost::log::expressions::attr< boost::posix_time::ptime >("TimeStamp")
        % boost::log::expressions::smessage
        );
sink->set_filter(channel == motion_check_channel);
core->add_sink(sink);

如何让boost.log处理UTF8文件名?

Boost.Log 以底层操作系统的本机编码组成文件名。在 Windows 上,文件名是 UTF-16 字符串(字符类型是 wchar_t),在大多数 POSIX 系统上,它通常是 UTF-8(字符类型是 char).

为了以本机编码生成文件名,as_file_name_composer 适配器创建一个流,在调用适配的格式化程序时根据需要执行字符代码转换。这基本上允许您在格式化程序中使用窄字符串和宽字符串,只要编码可以转换为本机编码即可。您必须知道相同类型的字符串被假定具有相同的编码,因此如果本机多字节编码是 UTF-8,那么您的所有窄字符串也必须是 UTF-8。

当发生字符代码转换时,流使用您可以提供的语言环境作为 as_file_name_composer 的第二个参数。默认情况下,语言环境是默认构造的。如果您默认构造的语言环境不是 UTF-8,那么转换将产生不正确的结果,我认为这就是正在发生的事情。您必须将全局语言环境设置为 UTF-8 或创建 UTF-8 语言环境并将其传递给 as_file_name_composer 适配器。您可以使用 Boost.Locale 轻松生成 UTF-8 语言环境。