« BGFX 的一个 lua 封装库 | 返回首页 | 近期在 bgfx 上做的一些工作 »

给 Lua 在 windows 下换上 utf-8 文件名支持

最近在 windows 做开发比较多,lua 原生库使用的都是 C 标准库中的函数,比如文件操作就是用的 fopen 打开文件。这对 unicode 支持的很糟糕。我希望所有和文件名打交道的地方都使用 utf-8 编码,所以今天花了一点时间实现了这么一个库。

我把 lua 原生库中和文件名有关的 api 都重新实现了一遍,包括了:loadfile , dofile , os.rename , os.remove , os.execute, os.getenv , 以及 io.open 。除了 require 都可以在接口上使用 utf-8 字符串了。这里 require 是偷懒没支持 :)

用的比较多的 lfs 库也缺乏 utf-8 支持,我挑选了一部分 api 改写了 utf-8 版本。其中包括 lfs.dir , lfs.currentdir, lfs.chdir, lfs.touch, lfs.mkdir, lfs.rmdir, lfs.attributes 。

对于 windows 还有两个特别的新 api 很可能用得上:

winfile.shortname 可以用来获取短文件名,这样可以很好的去除掉长文件名中的空格。

winfile.personaldir 用来获取 My Document 目录。我可不想在 windows 下使用注册表来保存数据,还是去我的文档下建个目录来存放比较好。

最后: github 仓库传送门

Comments

@cloud Don't feed the troll.

这个还不简单?用当前编码页啊。你的显示API如果只支持unicdoe,你也可以这样转成unicode。MultiByteToWideChar(CP_ACP, 0, info, -1, buf, int(len));
当然直接写在lua里我是不推荐的。但也不是不可以,无论你写在程序里还是ini里。记得文本文件保存成你想要的代码页就行了啊。中文就成gb2312格式ok。

问题在于:

"f:/用户目录/config.lua" 这样一个字符串如果是写在你的源代码里的,你打算怎么编码你的源代码。

如果你打算把这个字符串写到配置文件中,用什么编码组织配置文件。

如果你需要把这个目录字符串显示在屏幕上,你打算用什么编码传给你的显示 api 。

好吧,即使如此。我感觉还是不需要去改utf8.比如用户是简体中文的操作系统。他的目录名一般不会是日文吧?那使用fopen("f:/用户目录/config.lua");这类的操作应该是不会出错的吧?除非有可能打开的目录又有一种以上编码的我感觉才需要用到utf8。

首先,我有说我最近在做游戏开发么? :)

用户目录指的是用户自己的数据文件的目录,并非软件目录。

windows 早就加强了权限管理,软件目录通常是不可改写的。

用户数据文件,例如配置信息、存档、截图、等等都是放在用户目录下。而用户目录的位置是由用户指定的,默认会在我的文档下,一般更友好的交互界面还会有 GUI 界面设定,这个界面上是需要显示完整路径的。

此外,游戏开发还包括了开发工具、提供给用户的 mod 工具等等。

@dwing
UTF8 TO ASCII 就是搞笑,UTF8是可以同时包含多个字符集的。就像皇室战争的用户名可以是任意国家的的字符编码而且同时出现,ASCII可是做不到。

我公司的游戏运营都10年了,也使用lua,用户当然也是可以安装到任意路径,我们是没有做什么utf-8这种处理的。还重来没听说过有什么问题。就是你的资源文件和目录得是ascii。

然后就算用全路径也不是不可以。只要你的资源里路径都是ascii。即时用户安装到中文目录,那也没关系。使用fopen也是可以打开的。因为是这时用的是当前操作系统的编码页。都是中文。除非说用户安装了一个和当前操作系统不一样字符集的一个目录,这个是比较奇葩的吧。现在的win7,win10我没试过,早期的windows一定是显示???的,不要说你打不开。

全路径并不理由,首先你打开文件的路径使用从你的游戏根目录开始的相对路径就可以了。没有必要从盘符开始算路径。然后你们的资源不打包的吗?如果打包的话用全路径有什么意义?你们的包里面的文件列表难道有可能保存了用户的安装路径?

用户目录的全路径可能有中文,这个是用户自己设置的,并非开发者设定。

文件名规定都使用小写字母不好吗,使用标准ascii码来命名不好吗?想要支持unicode当然也是很容易办到的.但是感觉不值得。你开发的游戏用汉字做文件名。如果有海外版本,看起来总觉的怪怪的。

Lua报错那儿也不支持utf-8,有时候会直接截断utf-8字符,导致 to utf16的时候直接失败。。。无语。

能加个友链吗?

同楼上做法。这样不是更容易么。。。

各有优劣吧。此外,云风的实现了还有少了io.lines/io.popen/package.loadlib/package.searchpath

utf8 to ansi 不一定能转换成功(比如韩文文件名在中文系统中打开),
还是utf8 to ucs2 然后调用windows的unicode api比较通用.

我的做法是实现一个utf8 to ansi的函数,然后把要用到的api重载下。这样比较简单。

程序数据是不是放appdata比较好?

Post a comment

非这个主题相关的留言请到:留言本