我与macOS、exFAT、妖精帝國的一场约会

救世blah blah blah

客栈的老读者可能知道,我们有着发现 macOS 与 Windows 之间各种神奇的日常兼容问题的老传统

今天咱们带来一个有点小众,但让人寝食不安的文件名兼容问题——

在 Windows 上完全正常的文件,在 macOS Finder 和 Terminal 都无法找到。不仅如此,还没法删除。

但这个故事要从日本哥特摇滚乐团「妖精帝國」的专辑「救世Άργυρóϛ」说起。

2014 年,妖精帝國发布的专辑「救世Άργυρóϛ」里包含了这么一首歌:「Ēlusion」,意为「成功逃脱」或「无法企及」的意思。当然,macOS 和 Windows 都不会因为她的歌词难懂而闹别扭。

同年,我在 OS X Yosemite 10.10 或者 Mavericks 10.9 下载了这首歌并保存为 03 - Ēlusion.mp3。由于 Apple File System(APFS)还不存在,该文件名继承 HFS+ 的惯例,使用 Unicode 的 NFD 形式保存。

时光流逝,这首歌辗转到了我的 Windows 10 + NTFS 系统上,由于 NTFS 只在意 UTF-16,文件名保持了原本的 NFD 形式。

一切安好,直到最近我尝试用 exFAT 格式的移动硬盘,把这首歌从 Windows 复制到 macOS 上。

挂起硬盘一看,macOS Finder 和 Terminal 下的 ls -la 都找不到这个文件。我甚至无法删除包含这歌的文件夹。在排除了硬盘问题和妖精作怪之后,我开始往 Unicode 文件名的角度思考——

  • 不少开发者知道,OS X 处理 Unicode 文件名的方式与 Windows、Linux 不同
  • 具体地说,OS X 与 HFS+,在 El Capitan 10.11 之前,一直都强制 NFD 形式。
  • 但在 macOS 10.13 与 APFS 之后,苹果不再强制 NFD,只是在 system calls 和 command line 上转化输出为 NFD。APFS 底层变为同时支持 NFC 和 NFD 形式。

但这个信息并没有解决我的问题,macOS 明明支持 NFD 和 NFC 文件名了,怎么还会有这种文件无法显示的问题?

答案是,和妖精帝國晦涩的歌词一样,当你在 macOS 挂起 exFAT 硬盘,macOS 似乎默认上面的文件用 NFC 形式的文件名

要测试这个行为并不难,我准备好了以下三个文件:

  • test.mp3
  • Ēlusion.mp3 – 这里 Ē 是 NFC 形式。
  • 03 - Ēlusion.mp3 – 这里 是 NFD 形式。

如果你要一个形象的对比,可以到这里看

在 Windows 上,一切正常:

windows filenames

因为 NTFS 只在乎 UTF-16 字串,你甚至可以用「看起来」一样的文件名。

windows filenames

但到了 macOS + exFAT 上:

macos filenames

ls -la 的结果:

$ ls -la
total 46592
drwxrwxrwx  1 df  staff    131072 Jan  3  2017 .
drwxrwxrwx  1 df  staff    131072 Jan  3  2017 ..
-rwxrwxrwx  1 df  staff  11672464 Aug 23  2014 Ēlusion.mp3
-rwxrwxrwx  1 df  staff  11672464 Aug 23  2014 test.mp3

可见,和 macOS 升级的变化恰恰相反:最早强制的 Unicode NFD 文件名,反而无法显示了

事实上,假如你有重复名字的文件,ls -la 的结果还会变化。

例如说,把 test.mp3 改名为 03 - Ēlusion.mp3

macos filenames

$ ls -la
total 69632
drwxrwxrwx  1 df  staff    131072 Jan  3  2017 .
drwxrwxrwx  1 df  staff    131072 Jan  3  2017 ..
-rwxrwxrwx  1 df  staff  11672464 Aug 23  2014 03 - Ēlusion.mp3
-rwxrwxrwx  1 df  staff  11672464 Aug 23  2014 03 - Ēlusion.mp3
-rwxrwxrwx  1 df  staff  11672464 Aug 23  2014 Ēlusion.mp3

欢迎你推测这背后发生了什么鬼。

总结此事,我得出了几个结论:

  • 别在跨平台的情景用 Unicode 文件名,尤其当这个平台包括 macOS。
  • exFAT 看似美好:支持 4GB+ 文件、兼容 macOS / Windows、无需额外软件。但坑还是难免。
  • 所有文件系统开发团队都需要一个喜欢日本动画歌曲的架构师。

感谢收看这期节目,我们下期再见(?

衍生阅读:External Drive, can’t empty trash, rm sees a file, but ls -la doesn’t

Author: 店长

The Master of BitInn

3 thoughts on “我与macOS、exFAT、妖精帝國的一场约会”

Comments are closed.