我正在使用zlib阅读gzip压缩文件.然后使用打开文件
gzFile gzopen(const char *filepath, const char *mode);
Run Code Online (Sandbox Code Playgroud)
如何处理存储const wchar_t*在Windows上的Unicode文件路径?
在类UNIX平台上,您只需将文件路径转换为UTF-8并调用gzopen(),但这在Windows上无效.
Mar*_*ler 13
下一版本的zlib将包含此函数,其中_WIN32#defined:
gzFile gzopen_w(const wchar_t *path, char *mode);
它的工作原理完全像gzopen(),除了它使用_wopen()而不是open().
我故意没有复制第二个参数_wfopen(),因此我没有调用它_wgzopen()来避免可能与该函数的参数混淆.因此这个名字gzopen_w().这也避免了使用C保留的名称空间.
dan*_*n04 11
文件名是以零结尾的字节序列.内核不需要关心字符编码(除了知道ASCII代码/).
但是,从用户的角度来看,将文件名解释为字符序列更方便,这可以通过指定为语言环境一部分的字符编码来完成. 通过使UTF-8语言环境可用来支持Unicode.
在C程序中,文件用普通char*字符串表示,如fopen. POSIX API没有宽字符版本. 如果您有wchar_t*文件名,则必须将其显式转换为char*.
文件名是UTF-16代码单元的序列.实际上,Windows中的所有字符串操作都是在内部以UTF-16完成的.
所有Microsoft的C(++)库(包括Visual C++运行时库)都使用char*字符串在特定于语言环境的旧"ANSI"代码页中的约定,字符串使用wchar_t*UTF-16.这些char*函数只是围绕新wchar_t*函数的向后兼容包装器.
所以,如果你打电话MessageBoxA(hwnd, text, caption, type),这与打电话基本相同MessageBoxW(hwnd, ToUTF16(text), ToUTF16(caption), type).当你打电话时fopen(filename, mode),就像_wfopen(ToUTF16(filename), ToUTF16(mode)).
请注意,这_wfopen是用于处理wchar_t*字符串的许多非标准C函数之一.这不仅仅是为了方便; 您不能使用标准char*等效项,因为它们将您限制为"ANSI"代码页(不能是UTF-8).例如,在windows-1252语言环境中,您不能(轻松)fopen该文件????.c,因为无法在窄字符串中表示这些字符.
一些典型的方法是:
char*字符串一起使用,并且不要在Windows上提供对非ANSI字符的支持.char*字符串但将其解释为UTF-8而不是ANSI.在Windows上,编写包含UTF-8参数的包装函数,将它们转换为UTF-16,并调用函数_wfopen.不幸的是,它似乎使用上面的天真方法#1,open而不是_wopen直接使用(而不是).
除了已经提到的解决方案(我最喜欢的是Appleman1234的gzdopen建议)之外,你可以利用符号链接为文件提供一个替代的全ASCII名称,然后你可以安全地传递给它gzopen.如果文件已经有合适的短名称,您甚至可能不必这样做.