我有一个字符串“Château”,带有UTF-8编码&它被转换为US-ASCII格式为“Ch ?? teau”(在我的应用程序的底层库中)
现在,我希望从“U-ASCII”转换后的字符串“Ch ?? teau”中获取原始字符串“Château”。但是,我无法使用以下代码获得它。
StringBuilder masterBuffer = new StringBuilder();
byte[] rawDataBuffer = (Read from InputStream) // say here it is "Château"
String rawString = new String(rawDataBuffer, "UTF-8");
masterBuffer.append(rawString);
onMessageReceived(masterBuffer.toString().getBytes()) => Here, getBytes() uses the platform's default charset 'US-ASCII.
我的应用程序收到US-ASCII编码的字节数组。 在应用程序方面,即使我试图从中获取UTF-8字符串,也没用。 转换尝试仍然提供“Ch ?? teau”。
String asciiString = "Ch??teau";
String originalString = new String(asciiString.getBytes("UTF-8"), "UTF-8");
System.out.println("orinalString: " + originalString);
'originalString'的值仍然是“Ch ?? teau”。
这是正确的方法吗?
谢谢,
答案 0 :(得分:3)
你做不到。您通过转换为US-ASCII丢失了信息。你无法找回失去的东西。
答案 1 :(得分:1)
您的代码正在接收UTF-8编码的字节数组,正确将其转换为Java String
,但然后将该字符串转换为ASCII编码的字节数组。 ASCII不支持Ã
和¢
字符,这就是它们被转换为?
的原因。转换完成后,就不会再回头了。 ASCII是UTF-8的子集,ASCII中的?
在UTF-8中也是?
。
解决方案是停止转换为ASCII以开始。您应该转换回UTF-8:
StringBuilder masterBuffer = new StringBuilder();
byte[] rawDataBuffer = ...; // Read from InputStream
String rawString = new String(rawDataBuffer, "UTF-8");
masterBuffer.append(rawString);
onMessageReceived(masterBuffer.toString().getBytes("UTF-8"));
至少就这种方式而言,对于真正的ASCII字符,接收器永远不会知道差异(因为ASCII是UTF-8的子集),并且非ASCII字符不会再丢失。接收器只需要知道期望UTF-8而不是ASCII。而且,您的代码将更具可移植性,因为您将不再依赖于特定于平台的默认字符集(并非所有平台都默认使用ASCII)。
当然,在您的示例中,您的StringBuilder
是多余的,因为您没有向其添加任何其他内容,因此您可以将其删除:
byte[] rawDataBuffer = ...; // Read from InputStream
String rawString = new String(rawDataBuffer, "UTF-8");
onMessageReceived(rawString.getBytes("UTF-8"));
然后String
也变得多余了:
byte[] rawDataBuffer = ...; // Read from InputStream
onMessageReceived(rawDataBuffer);
如果onMessageReceived()
期望字节作为输入,为什么浪费开销将字节转换为字符串再次转换为字节?