我们有一个数据库,我们保存字节数组(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) �
答案 0 :(得分: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解码器将用替换字符替换所有格式错误的字节序列(甚至中止解码,具体取决于解码器及其设置)。
答案 1 :(得分:0)
您可以使用Hbase API提供的Bytes类。例如,将字节数组转换为字符串,您可以使用“Bytes.toString(byteArray)”。