vro*_*oom 41 windows unicode ntfs
我刚刚开始编写一些程序来处理WinXP系统上具有非英文名称的文件名.我已经完成了一些关于unicode的推荐阅读,我认为我得到了基本的想法,但有些部分对我来说仍然不是很清楚.
具体来说,什么编码(UTF-8,UTF-16LE/BE)是存储在NTFS 中的文件名(不是内容,而是文件的实际名称)?是否可以使用fopen()打开任何文件,它接受一个char*,或者我别无选择,只能使用wfopen(),它使用wchar_t*,并且可能需要一个UTF-16字符串?
我尝试手动输入UTF-8编码的字符串给fopen(),例如.
unsigned char filename[] = {0xEA, 0xB0, 0x80, 0x2E, 0x74, 0x78, 0x74, 0x0}; // ?.txt
FILE* f = fopen((char*)filename, "wb+");
Run Code Online (Sandbox Code Playgroud)
但这就是'ê°€.txt'.
我觉得UTF8编码的字符串足以打开Windows下的任何文件名,因为我似乎依稀记得一些Windows应用程序传递(char*),而不是(wchar_t*),并且没问题.
任何人都可以对此有所了解吗?
vil*_*pam 37
NTFS以UTF16存储文件名,但fopen使用ANSI(不是utf8).
要使用UTF16编码的文件名,您需要使用文件打开调用的Unicode版本.通过在项目中定义UNICODE和_UNICODE来完成此操作.然后使用CreateFile调用或wfopen调用.
Chr*_*cke 14
fopen() - 在Windows上的MSVC中(默认情况下)不采用utf-8编码的char*.
不幸的是,utf-8最近才发明在伟大的计划中.Windows API分为Unicode和Ansi版本.采用或处理字符串的每个窗口api实际上都有W或A后缀 - W表示"宽"字符/ Unicode,A表示Ansi.Macro magic将所有这些隐藏在开发人员之外,因此您只需使用char*或wchar_t*调用CreateFile,具体取决于您的构建配置,而不知道区别.
'Ansi'编码实际上不是特定的编码: - 但意味着用于"char"字符串的编码特定于PC的语言环境设置.
现在,因为c-runtime函数 - 比如fopen - 需要在没有开发人员知识的情况下默认工作 - 在Windows系统上,他们希望在windows本地编码中接收它们的字符串.msdn表示微软的c-runtime api setlocal可以改变当前线程的语言环境 - 但是具体说它对于每个字符需要超过2个字节的任何语言环境都会失败 - 比如utf-8.
因此,在Windows上没有捷径.您需要使用wfopen或本机API CreateFileW(或使用Unicode构建设置创建项目,只需调用Createfile)和wchar_t*字符串.
正如其他人所回答的,处理UTF-8编码字符串的最佳方法是将它们转换为UTF-16并使用本机Unicode API,如_wfopen或CreateFileW.
但是,这种方法在调用fopen()无条件使用的库时无济于事,因为它们不支持Unicode,或者因为它们是用便携式C编写的.在这种情况下,仍然可以利用传统的"短路径"来转换将UTF-8编码的字符串转换成可用的ASCII格式fopen,但需要一些脚法:
使用将UTF-8表示转换为UTF-16 MultiByteToWideChar.
使用GetShortPathNameW获得"短路径",这是ASCII只.GetShortPathNameW将它作为带有全ASCII内容的宽字符串返回,您需要通过每个无损复制转换将其简单地转换为窄字符串wchar_t char.
将短路径传递fopen()给最终将使用的代码fopen().请注意,该代码打印的错误消息(如果有)将引用难看的"短路径"(例如KINTO~1代替kinto-un-???).
虽然这不是一个推荐的长期策略,但由于Windows短路径是可以按卷关闭的传统功能,因此它可能是将文件名传递给使用的代码fopen()和其他与文件相关的API调用的唯一方法(stat,accessANSI版本CreateFile和类似版本).
| 归档时间: |
|
| 查看次数: |
38670 次 |
| 最近记录: |