问题 在Java中,为什么WindowsPreferences使用斜杠作为大写字母?


我一直在使用java.util.prefs.Preferences功能(在Java 8中,在Windows机器上)。它可以工作,我可以在其中写入Windows注册表的新密钥。因此,我使用Preferences.systemRoot()来获取系统的Preferences对象,然后使用node()方法获取映射到Windows注册表中的节点的Preferences对象。它创造了很好的东西。

我用于节点的密钥是所有大写字母的字符串(“RBI”)。当我查看Windows注册表中的节点时,它会显示为“/ R / B / I”,名称中带有正斜杠。

我觉得这很奇怪,所以我挖了一下而且看起来这是故意的。我找到了在Windows环境中提供Preferences实现的类(java.util.prefs.WindowsPreferences),该方法用于构建发送到Windows注册表的值是一个静态方法toWindowsName。在JavaDoc中......

/**
 * Converts value's or node's name to its Windows representation
 * as a byte-encoded string.
 * Two encodings, simple and altBase64 are used.
 * <p>
 * <i>Simple</i> encoding is used, if java string does not contain
 * any characters less, than 0x0020, or greater, than 0x007f.
 * Simple encoding adds "/" character to capital letters, i.e.
 * "A" is encoded as "/A". Character '\' is encoded as '//',
 * '/' is encoded as '\'.
 * The constructed string is converted to byte array by truncating the
 * highest byte and adding the terminating <tt>null</tt> character.
 * <p>
 * <i>altBase64</i>  encoding is used, if java string does contain at least
 * one character less, than 0x0020, or greater, than 0x007f.
 * This encoding is marked by setting first two bytes of the
 * Windows string to '/!'. The java name is then encoded using
 * byteArrayToAltBase64() method from
 * Base64 class.
 */

因此,对于大写字母,简单编码将添加正斜杠。

有谁知道为什么这是必需的?我以为注册表可以处理区分大小写的值,但这似乎表明它不能?

我可以解决这个问题,我只是好奇为什么要这样做。


11500
2018-04-10 23:54


起源

听起来他们试图让命名方案区分大小写。 - Harry Johnston
同意,但是使用RegEdit我可以输入区分大小写的字符串(其中有很多已经存在)。并使用其他工具选项。也许这是对最终使用本机方法的调用的一些解决方法。 - EdH
看起来它将String编码为字节数组。哪个好。现在,我能想到的唯一原因(那些关键的最后四个字)就是如果你没有大小写字母的不同字节值。但是,据我所知,小写和大写字母确实有不同的字节值。那么,这不是真的有必要吗?我肯定错过了什么 - EdH
不,注册表中的名称是保留大小写但不区分大小写的。您不能在同一个键中具有名为“Fred”的值和名为“fred”的值。 - Harry Johnston
有趣。我没有意识到这一点。 - EdH


答案:


我很好奇你和我发现了以下解释:

Registry-Keys是保留大小写的,但不区分大小写。例如,如果您有一个键“Rbi”,则无法创建另一个名为“RBi”的键。案例已保存但被忽略。 Sun的区分大小写的解决方案是为密钥添加斜杠。

Registry-Values区分大小写(当然还有大小写保留)。我不认为Sun也打算在数值中添加斜杠,但不知怎的,它已经进入了代码。在我看来,这个错误很长一段时间都没有找到。当发现错误时,许多系统已经依赖于错误的实现,因此他们从未删除它以保持兼容性。

如果您不喜欢Registry-Values中的斜杠,您可能会对此感兴趣 这个实现


13
2018-05-13 13:42