0

我们有一个保存字节数组(HBase)的数据库。我们所有的字符串都被编码为字节,我们手动进行转换。但是,一些旧数据被错误地保存了,不知道有没有办法恢复它们。

发生的事情是我们有一些原始文本被编码,比方说,在 ISO_8859_1 但是,将这些字符串保存为字节数组的过程做了类似的事情new String(original_bytes, UTF8).getBytes(UTF8) (而 original_bytes 将字符串表示为 ISO8859_1)

我找不到恢复 original_bytes 数组的方法。它实际上可能吗?

我尝试使用这个简单的 Java 示例代码重现它:

String s = "é";
System.out.println("s: " + s);
System.out.println("s.getBytes: " + Arrays.toString(s.getBytes()));
System.out.println("s.getBytes(UTF8): " + Arrays.toString(s.getBytes(Charsets.UTF_8)));
System.out.println("new String(s.getBytes()): " + new String(s.getBytes()));
System.out.println("new String(s.getBytes(), UTF-8): " + new String(s.getBytes(), Charsets.UTF_8));

byte [] iso = s.getBytes(Charsets.ISO_8859_1);
System.out.println("iso " + Arrays.toString(iso));
System.out.println("new String(iso)" + new String(iso));
System.out.println("new String(iso, ISO)" + new String(iso, Charsets.ISO_8859_1));
System.out.println("new String(iso).getBytes()" + Arrays.toString(new String(iso).getBytes()));
System.out.println("new String(iso).getBytes(ISO)" + Arrays.toString(new String(iso).getBytes(Charsets.ISO_8859_1)));
System.out.println("new String(iso, UTF8).getBytes()" + Arrays.toString(new String(iso, Charsets.UTF_8).getBytes()));
System.out.println("new String(iso, UTF8).getBytes(UTF8)" + Arrays.toString(new String(iso, Charsets.UTF_8).getBytes(Charsets.UTF_8)));

输出:(在默认字符集为 UTF8 的计算机上)

s: é
s.getBytes: [-61, -87]
s.getBytes(UTF8): [-61, -87]
new String(s.getBytes()): é
new String(s.getBytes(), UTF-8): é
iso [-23]
new String(iso)�
new String(iso, ISO)é
new String(iso).getBytes()[-17, -65, -67]
new String(iso).getBytes(ISO)[63]
new String(iso, UTF8).getBytes()[-17, -65, -67]
new String(iso, UTF8).getBytes(UTF8)[-17, -65, -67]
new String(new String(iso).getBytes(), Charsets.ISO_8859_1) �
4

2 回答 2

0

不幸的是,不,并非在每种情况下都是可能的。

UTF-8 有很多非法的字节序列,在解码时(通常)会被一些替换字符替换。当您original_bytes包含任何这些字节序列时,该信息肯定会丢失。

你最好的选择是做相反的事情,这可能会让你尽可能接近原始字符串:

byte[] originalISOData = ...;
byte[] badUTF8 = new String(originalISOData, "UTF-8").getBytes("UTF-8");
byte[] partialReconstruction = new String(badUTF8, "ISO-8859-1");

tl;dr将非 UTF-8 数据解码为 UTF-8通常不是无损操作。有效的 UTF-8 解码器将用替换字符替换所有格式错误的字节序列(甚至中止解码,具体取决于解码器及其设置)。

于 2012-05-14T08:09:18.940 回答
0

您可以使用 Hbase API 提供的 Bytes 类。例如,将字节数组转换为字符串,您可以使用“Bytes.toString(byteArray)”。

于 2012-05-23T22:08:38.393 回答