【发布时间】:2021-04-25 20:58:41
【问题描述】:
短版:
将包含值 55296 和 57343(含)之间的字符的字符串写入文件会导致这些字符被问号 ('?') 替换,这意味着无法将生成的文件读回原始字符串。
如何避免/规避这个问题?
长版:
我有一个介于 0 和 65535(含)之间的整数数组,我正在尝试将其写入文件,以便稍后检索该数组。下面是一个示例数组:
int[] integerArray = new int[] {2404,44698,55597,17382,35641,10988};
了解 unicode 正好有 65536 个字符,而 Java 的 char 数据也有 65536 个值,我决定通过将这些整数中的每一个转换为一个字符,将它们添加到一个字符串,然后将该字符串写入一个文件来做到这一点像这样:
private static void writeUnicodeToFile(int[] array, String path) {
String unicode = "";
for(int integer : array) unicode += (char) integer;
try { Files.write(Path.of(path), unicode.getBytes());
} catch(IOException e) { e.printStackTrace(); }
}
这在大多数情况下是有效的,但是在示例数组的情况下,转换值 55597 会返回问号 ('?') 字符,因此当我尝试像这样检索值时:
private static int[] getUnicodeFromFile(String path) {
String unicode = "";
try { unicode = Files.readString(Path.of(path));
} catch(IOException e) { e.printStackTrace(); }
int[] integerArray = new int[unicode.length()];
for(int i = 0; i < unicode.length(); i++) integerArray[i] = (int) unicode.charAt(i);
return integerArray;
}
返回的数组在索引 2 处包含 63(问号的 unicode id)而不是 55597。
在 unicode 字符表中搜索值 55597 发现它不是一个有效字符,进一步实验发现 unicode 中有 2049 个字符将作为问号写入文件(包括问号本身) .所有其他字符都可以正常读写。
但是,这意味着无法将文件解码回整数数组,因为一个字符可以解释为其他 2048 个字符。
那么我怎样才能将所有这些字符彼此区分开来,以便我可以在文件中读取/写入它们而不会相互干扰呢?
或者,我可以以某种方式使用不同的字符集来完全避免这个问题吗?我可以灵活地将每个整数转换为从 0 到 255 的两个值,并使用其他一些文本文件编码设置。
其他可能相关的信息:
我正在使用 Eclipse IDE,并将我的工作区的文本文件编码设置为 UTF-8(我理解它等同于 unicode)。
【问题讨论】:
-
关于 "...unicode 正好有 65536 个字符...",这从来都不是真的。大约 25 年前,Unicode 的理论最大字符集大小为 65,536,但现在没有实际限制。请参阅How many Unicode characters are there? 这与您的问题没有直接关系,但仍然值得澄清。
标签: java unicode character-encoding