许多时候需要查看日志中的中文字符,但是protobuf中某字段为中文的话,打印出来为8进制字符。若要打印为中文,可用以下代码:
import com.google.protobuf.TextFormat;
public class NormalProtobufDeserializer implements IProtobufDeserializer{
@Override
public String deserial(byte[] data) {
String ret = "";
try{
NormalDeserializer.NormalMessage normalMessage = NormalDeserializer.NormalMessage.parseFrom(data);
//ret = normalMessage.toString(); 此时为8进制,如"\241\242\243\244\245"
ret = TextFormat.printToUnicodeString(normalMessage);
}catch (Throwable throwable){
}
return ret;
}
若已经打印出八进制”\241\242\243\244\245”,可以用以下代码转成中文:
public static void printProtoBuf(String dataStr) {
if (!dataStr.contains("\\")) {
System.out.println("未识别:" + dataStr);
} else {
//不属于八进制内容的字符
StringBuilder oldBuffer = new StringBuilder();
//属于八进制的内容,转成十六进制后缓存在这里
StringBuilder hexBuffer = new StringBuilder();
for (int i = 0; i < dataStr.length(); i++) {
char c = dataStr.charAt(i);
if (c != '\\') {
oldBuffer.append(c);
}
//反斜杠往后3个为一组,组成了一个八进制数。例如\20710,其实是207组成了一个八进制数
else {
char c1 = dataStr.charAt(i + 1);
char c2 = dataStr.charAt(i + 2);
char c3 = dataStr.charAt(i + 3);
if(c1 == 'n' && c2 == '\\'){
i += 1;
oldBuffer.append("\n");
}else if(c1 == 't' && c2 == '\\'){
i += 1;
oldBuffer.append("\t");
}else if(c1 == 'f' && c2 == '\\'){
i += 1;
oldBuffer.append("\f");
}else {
i += 3;
//将八进制转换为十进制,再转换为十六进制
String hex = Integer.toHexString((Integer.valueOf("" + c1 + c2 + c3, 8)));
//先缓存住,直到凑够三个字节
hexBuffer.append(hex);
String hexString = hexBuffer.toString();
//utf8编码中,三个字节为一个汉字
if (hexString.length() == 6) {
//凑够三个字节了,转成汉字后放入oldBuffer中
oldBuffer.append(hexStr2Str(hexString));
//凑够一个汉字了,清空缓存
hexBuffer = new StringBuilder();
}
}
}
}
System.out.println("解码后:" + oldBuffer.toString());
}
}