跨平台unicode路径处理

时间:2009-11-20 08:06:05

标签: c++ unicode boost winapi cross-platform

我正在使用boost::filesystem进行跨平台路径操作,但是当需要将调用转换为我无法控制且不接受UTF-8的接口时会出现故障。例如,当使用Windows API时,我需要转换为UTF-16,然后调用我要调用的任何函数的宽字符串版本,然后将任何输出转换回UTF-8。

虽然许多boost :: filesystem函数的wpath和其他w*形式有助于保持理智,但是有什么建议可以在需要时如何最好地处理这种转换为宽字符串形式,同时保持我自己的代码的一致性?

3 个答案:

答案 0 :(得分:2)

最简单的方法是制作某种通用例程,它会以你想要的路径或路径周围的包装类的方式返回字符串编码。

boost::filesystem::wpath boostPath( L"c:\\some_path" );
MyPathWrapper p( boostPath );
std::wstring sUtf8 = p.file_string_utf8();
std::wstring sUtf16 = p.file_string_utf16();
// or
std::wstring sUtf8 = p.file_string( CP_UTF8 );
// ...

类似的东西。

答案 1 :(得分:1)

我做了什么:

struct vpath_traits;

typedef boost::filesystem::basic_path<std::string, vpath_traits> vpath;

// utf8 
struct vpath_traits
{
  typedef std::string internal_string_type;
  typedef std::wstring external_string_type;
  static external_string_type to_external(
      const vpath &, const internal_string_type &src);
  static internal_string_type to_internal(const external_string_type &src);
};


namespace boost {
  namespace filesystem {
    template<> struct is_basic_path<vpath>
    { BOOST_STATIC_CONSTANT( bool, value = true ); };
  }
}

// convenient functions for converting vpath to and from
// whatever API you may be using.

std::string    vpathToWin32Byte(const vpath &src);
vpath          vpathFromWin32Byte(const std::string &str);
vpath          vpathFromWin32Byte(const char *str);

std::wstring   vpathToWin32Wide(const vpath &src);
vpath          vpathFromWin32Wide(const std::wstring &str);
vpath          vpathFromWin32Wide(const wchar_t *str);

QDir           vpathToQDir(const vpath &src);
vpath          vpathFromQDir(const QDir &qdir);

注意:

你必须以某种方式实现方法vpath_traits::to_externalvpath_traits::to_internal。可能有一些utf8转换器 促进。然而,我将utf8实现为ucs-16并支持自己,但确实如此 既不漂亮也不完整,所以你最好使用一些标准 实施

它适用于我们的代码。 E g:

namespace fs = boost::filesystem;
...

vpath dstFile = dstDir / filePath;
bool success = true;

try { fs::remove(dstFile); }
catch (fs::basic_filesystem_error<vpath> & /* e */) { success = false;}

if (success) {
  try { fs::copy_file(srcFile, dstFile); }
  catch (fs::basic_filesystem_error<vpath> & /* e */) { success = false;}
}

...

答案 2 :(得分:0)

什么对我有用:

  • Windows:std :: wstring是utf16,所以“:: CreateFileW(Path.file_string()。c_str(),”......工作
  • Posix:您需要转换为utf8,解决方案:UTF8 to/from wide char conversion in STL