【发布时间】:2013-02-02 08:46:05
【问题描述】:
我正在为一个类项目编写一些编组/解组例程,并且对 Java 在这种情况下的默认行为感到有些困惑。这是我的“幼稚”子例程,用于在字节流中写入和读取字符串:
protected static void write(DataOutputStream dout, String str)
throws IOException{
dout.writeInt(str.length());
dout.writeChars(str);
}
protected static String readString(DataInputStream din)
throws IOException{
int strLength = 2*din.readInt(); // b/c there are two bytes per char
byte[] stringHolder = new byte[strLength];
din.read(stringHolder);
return new String(stringHolder);
}
不幸的是,这根本行不通;默认情况下,字符以 UTF-16 格式编写,但 String(byte[]) 似乎假设每个字节都包含一个字符,并且由于 ASCII 字符在 UTF-16 中都以 0 字节开头,因此构造函数似乎只是放弃了返回一个空字符串。解决办法是改readString指定必须使用UTF-16编码:
protected static String readString(DataInputStream din)
throws IOException{
int strLength = 2*din.readInt();
byte[] stringHolder = new byte[strLength];
din.read(stringHolder);
return new String(stringHolder, "UTF-16");
}
我的问题是,为什么有必要这样做?由于 Java 默认使用 UTF-16 作为字符串,为什么在从字节读取字符时不假设使用 UTF-16?或者,为什么不默认将字符编码为字节?简而言之,为什么writeChars() 方法和String(byte[]) 构造函数的默认行为不相互平行?
【问题讨论】:
-
使用
DataOutputStream.writeUTF()和DataInputStream.readUTF()怎么样? -
....哇,这样方便多了。谢谢你。我仍然很好奇为什么我的方法没有按预期工作,但我想我会改用这些方法。
-
我发布了一个完整的解释,希望能解决问题。
标签: java string character-encoding marshalling unmarshalling