4

Subversion的Wikipedia 条目包含一段关于不同 Unicode 编码方式的问题:

虽然 Subversion 将文件名存储为 Unicode,但它没有指定是否对某些重音字符(例如 é)使用预合成或分解。因此,在某些操作系统(如 OS X)上运行的 SVN 客户端中添加的文件使用分解编码,而在其他操作系统(如 Linux)上运行的客户端使用预合成编码,结果是这些重音字符无法正确显示,如果本地 SVN 客户端未使用与用于添加文件的客户端相同的编码

虽然这描述了 Subversion 客户端实现的特定问题,但我不确定底层 Unicode 组合问题是否也会出现在常规 Delphi 应用程序中。我猜这个问题只有在 Delphi 应用程序能够同时使用这两种 Unicode 编码方式(可能在 Delphi XE2 中)时才会出现。如果是,Delphi 开发人员可以做些什么来避免它?

4

3 回答 3

6

有一个小的显示问题是,Windows 上使用的许多字体无法以理想的方式呈现分解的形式,即通过对字母和变音符号使用组合字形。相反,它回退到渲染字母,而不是在顶部覆盖独立的变音符号,这通常会导致视觉上不那么令人愉悦,可能是不平衡的字形。

然而,这不是从 wiki 引用的 Subversion 错误所讨论的问题。实际上,将包含组合或分解字符序列的文件名签入到 SVN 是完全可以的;SVN 既不知道也不关心组合,它只是按原样使用 Unicode 代码点。只要后端文件系统使文件名保持与放入时相同的状态,一切都很好。

Windows 和 Linux 都有同样对组合视而不见的文件系统。不幸的是,Mac OS X 没有。HFS+ 和 UFS 文件系统都在存储传入的文件名之前对分解的形式执行“规范化”,因此您返回的文件名不一定是您输入的 Unicode 代码点序列。

正是这种 [IMO: insane] 行为让 SVN 以及许多其他程序在 OS X 上运行时感到困惑。它特别容易受到影响,因为 Apple 碰巧选择了分解 (NFD) 作为它们的规范化形式,而其余的大多数程序世界使用组合(NFC)字符。

(它甚至不是真正的 NFD,而是不兼容的 Apple 专用变体。Joy。)

解决这个问题的最好方法是,如果可以的话,永远不要依赖存储的确切文件名。如果您只从给定名称读取文件,那很好,因为它会被规范化以匹配当时的文件系统。但是如果你正在阅读一个目录列表并试图将你在其中找到的文件名与你期望的文件名匹配——这就是 Subversion 正在做的——你会得到不匹配的结果。

要可靠地进行文件名匹配,您必须检测到您在 OS X 上运行,并在进行比较之前手动将文件名和字符串标准化为某种正常形式(NFC 或 NFD)。您不应该在其他将这两种形式视为不同的操作系统上执行此操作。

于 2011-08-21T17:22:54.593 回答
1

AFAICT,两种编码在显示时都应该产生相同的结果,并且都是有效的 Unicode,所以我不太明白那里的问题。如果遇到分解,显示例程应该能够处理这两种情况。代码点é应按原样显示,而仅应按é分解模式显示。

问题不是显示,IMO,而是比较,无论是相等(如果两者都使用不同的编码,则失败)或词法,即排序。正如大卫所说,这就是为什么应该标准化为一种编码的原因。这样就没有歧义了。

于 2011-08-21T15:02:57.840 回答
0

在任何处理文本的应用程序中都可能出现同样的问题。如何避免它取决于应用程序正在执行的操作,并且问题缺乏具体细节。大多数情况下,我认为您可以通过规范化文本来解决此类问题。这涉及在遇到编码歧义时使用单个首选表示。

于 2011-08-21T07:34:48.567 回答