1

TL;DR:在 Java 中,通过方法从字符串获得的字符charAt转换为字节是否总是产生相同的值?

我正在阅读用任意(我们不知道)字符编码编码的文件。我需要解析这些文件并查找某些单词,例如“TAG”。我对文件内容进行了一定的限制,例如“在查找标签时,“标签”的字节必须与其 ASCII 表示相同”。

例如,假设我有以下文件:
0x00 0x11 0x22 0x33 0x54 0x41 0x47 0x77 0x88 0x99 0xaa 0xbb
由于 T、A 和 G 的 ASCII 值分别为0x540x410x47我可以通过解析字节本身在文件中找到“TAG”。 但是,我需要对要查找的字节的值进行硬编码。为此,我调用'
0x00 0x11 0x22 0x330x54 0x41 0x470x77 0x88 0x99 0xaa 0xbb

StringcharAt(int i)方法并将 char 转换为一个字节。

例如,我将如何验证任意字节(称为b)来表示“T”的字节表示:
String tag = "TAG";
char t = tag.charAt(0);
if ((byte)t == b){
        //magic goes here, such as comparing the 'A' and the 'G'
}
注意:代码实际上并非如此,验证算法要优雅得多。

这在我的本地机器上运行良好。但是,这将在可能包含非常奇怪编码的机器上运行。让我担心的是,将使用获得的字符charAt转换为字节是否会产生不同的值,具体取决于机器。我知道 Java 总是char使用 UTF-16 字符编码对 s 进行编码,但我担心从字符串转换为字符然后再转换为字节时可能会产生奇怪的结果。

因此,简而言之,将通过charAt一个字节的方法总是产生相同的值?还是取决于外部因素?

谢谢你的帮助!

注意:我不能对字节本身进行硬编码(例如,在字节数组中),因为它们可能非常长并且将来可能会经常更改。

4

4 回答 4

3

java.lang.string.charAt将始终返回 16 位 UTF-16 字符,当您将其转换为字节时,该字符始终相同,但由于char是 16 位无符号数据类型,因此将其转换为 8 位有符号byte可能会给您带来不希望的行为。但是,如果您的源数据是 ASCII,您将获得您所期望的行为类型。

于 2012-07-24T18:31:23.847 回答
2

YescharAt (int)返回一个 Java 定义的 char 类型 (UTF-16),因此总是相同地转换为byte.

相反String.getBytes(),根据指定的字符集或操作系统的默认字符集(如果未指定)返回字节。

于 2012-07-24T18:30:07.973 回答
0

将 char 转换为 byte(byte)将在所有系统上为您提供相同的结果。

但是,很少需要混合charbyte. 你真的应该使用其中一个。正如您所怀疑的那样,混合这些概念可能会导致混淆。

于 2012-07-24T18:26:36.050 回答
0

您可以使用该Character.codePointAt(char c)方法,而不是直接对它们进行类型转换。这应该保证您每次都获得相同的结果。

于 2015-02-27T09:35:24.763 回答