Windows目录永远不会包含临时文件的非ASCII字符?

时间:2019-07-19 12:13:03

标签: windows winapi temporary-files hunspell

由于Windows的限制,Hunspell在Windows上使用MinGW 7.3.0,无法从具有非ASCII字符的位置加载字典文件。我已经尝试了一切[1],现在我将文件复制到没有ASCII字符的路径之前,先将其提供给Hunspell。将其复制到什么位置?

[1]

  1. Windows需要wchar_tstd::iostream.open()的支持才能正常工作,而MinGW无法实现
  2. std::filesystem可以解决此问题,但仅在GCC 8中可用
  3. Hunspell坚持自行加载文件,无法将读取的文件作为字符串传递给它

3 个答案:

答案 0 :(得分:3)

来自this bug tracker

  

在WIN32环境中,请使用以long开头的UTF-8编码路径   路径前缀\\?\以处理与系统无关的字符编码   和非常长的路径名(没有长路径前缀Hunspell   将fopen()与系统相关的字符编码一起使用,而不是   _wfopen())。

所以实际的解决方案似乎是:

  1. 调用GetFullPathNameWnormalize路径。因为paths with long path prefix val AllTrainingDATA_RDD_Final = AllTrainingDATA_RDD.map(_.split(",")).keyBy(_(X_COORD,Y_COORD)).mapValues(fields => ("CLASS")).groupByKey().collect() 会原样传递到NT API,所以是必需的。
  2. \\?\插入规范化路径(由于C字符串文字要求,反斜杠加倍)。
  3. 对于UNC路径,您必须直接使用“ UNC”设备(即L"\\\\?\\"L"\\\\server\\share"(感谢eryksun)
  4. 将路径编码为UTF-8,例如。 G。将WideCharToMultiByte()L"\\\\?\\UNC\\server\\share"一起使用。
  5. 将最终UTF-8编码的路径传递到Hunspell。

答案 1 :(得分:1)

“自然”适合的用途是使用用户选择的临时目录(或其子目录)(请参见%temp%GetTempPath())。但是,默认情况下,该值将包含用户名(可以包含“非ASCII”字符;例如c:\users\Ø¥Ć¼\AppData\LocalLow\Temp)或任意值(关于字符集)。

因此,最有可能最好选择一些目录

a)不包含get do中的禁区字符。例如,您选择的C:\ProgramData下的目录(例如应用程序名称)不包含非ASCII字符。

b)让用户决定将这些文件放置在何处,并确保不允许输入仅包含允许字符的路径。

c)将"short path name"传递给Hunspell,该文件不应包含非ASCII字符以与FAT文件系统特征兼容。例如,c:\temp\Ø¥Ć¼的短路径名称是c:\temp\571D~1

您可以使用cmd.exe /c dir /x查看目录的简称:

C:\temp>dir /x
...    
19.07.2019  15:30    <DIR>                       .
19.07.2019  15:30    <DIR>                       ..
19.07.2019  15:30    <DIR>          571D~1       Ø¥Ć¼

我不知道如何从MinGW调用GetShortPathName Win32 API,但是我认为这是可能的。

还请务必查看MSDN页面以获取上述功能的特征,例如并非在任何地方都支持短名称(例如SMB +请参阅下面的评论)。

答案 2 :(得分:-4)

看来mySuperFile.c : ${PYTHON373} $(ROOT)/lib/mySuperFileGenerate $(FILES_DIR) $(REPO_STATE_FILE) $(PYTHON373) $(ROOT)/lib/mySuperFileGenerate --out-dir=$(OUT_DIR) --repo=$(ROOT) --output=mySuperFile.c 仍然是您可以写给自己的有效路径。