我不确定我是否已经理解了这里的问题,如果我还没有理解,请直接说出来,然后我会编辑标题。
我的问题如下:
我有一台 Ubuntu 12.04 服务器(UTF-8 语言环境),用户通过 Web 应用或 Shell 上传文件。因此我无法控制命名约定。然后这些名称被放入 UTF8 MYSQL 数据库表中。
不幸的是,似乎有些文件包含我的数据库不喜欢的特殊字符。
一个这样的例子是́e
(eU+0301) 代替é
(U+00E9)。我的数据库不喜欢这种情况,因此用 替换了此类实例e?
。shell 本身要么在使用时正确显示了信息ls
,要么在当前文件夹路径中显示了损坏的“不存在”符号。我还看到了E??
代替́E
(EU+0301) 的类似情况(仅供参考,应该是É
(U+00C9))
这很令人头痛,因为我甚至似乎无法对find
具有此类字符的文件运行命令。
所以我的第一个问题是:是否有一个 shell 命令可以用来在上传时转换文件名?(我可以在文件夹上递归运行)理想情况下,它会将它们转换为适当的等效项,但我不在乎是否必须用任意字符(例如“_”)替换任何此类 unicode 序列。
提前致谢。
答案1
我试图回答这个问题,但最终我写了一篇关于 UTF-8 和字符转换的小文章。(因此我觉得这个问题很遗憾,非常接近题外话)
简而言之,您无法以合理的方式执行此操作,因为您没有可靠的方法来在编码之间强制转换字符。HTTP 和其他编码感知协议/格式将编码作为有效负载的一部分提供。文件名则不然,没有文件系统元数据来指示名称的编码方式。
这是一个流程问题。你无法控制上传文件的人将如何使用文件名中的字符位,因此除了处理你提供的原始字节外,你无法做任何事情。
您有三个选择:
- 运行一个自动化过程,丢弃文件名中含有无效 UTF-8 连续字符的所有内容。您最终仍会得到错误编码的文件名,但至少程序不会出错。理想情况下,您的数据库应该有一个UTF-8 编码。
- 将文件名按原样存储在数据库中,并且不允许 UTF-8 与数据库中的目标编码之间发生任何强制转换。您的数据库必须用一个单字节编码,这些字符串如果解释为 UTF-8 则可能无效。
- 彻底重新架构你正在做的事情。