我读到Java内部使用UTF-16编码。即我明白如果我喜欢:String var =“जनमत”;然后“जनमत”将在内部以UTF-16编码。因此,如果我将此变量转储到某个文件,如下所示:
fileOut = new FileOutputStream("output.xyz");
out = new ObjectOutputStream(fileOut);
out.writeObject(var);
文件“output.xyz”中字符串“जनमत”的编码是否为UTF-16?另外,如果我想通过ObjectInputStream从文件“output.xyz”读取,我是否可以获得该变量的UTF-16表示?
感谢。
答案 0 :(得分:5)
所以,如果我将这个变量转储到某个文件中......文件“output.xyz”中字符串“जनमत”的编码是否为UTF-16?
文件中字符串的编码将采用ObjectOutputStream
想要放入的任何格式。您应该将其视为只能由ObjectInputStream
读取的黑匣子。 (说真的 - 即使格式为IIRC well-documented,如果你希望用其他工具读取它,你应该自己将对象序列化为XML或JSON或其他任何东西。)
如果我想通过ObjectInputStream从文件“output.xyz”读取,我是否可以获得该变量的UTF-16表示?
如果您使用ObjectInputStream
读取文件,则会获得原始对象的副本。这将包括一个java.lang.String
,它只是一个字符流(不是字节) - 如果你希望通过getBytes()方法,你可以从中获得UTF-16表示(尽管我怀疑你不喜欢)实际上需要)。
总之,不要过于担心序列化的内部细节。如果您需要知道发生了什么,请自行创建文件;如果你只是好奇,请相信JVM做正确的事。
答案 1 :(得分:1)
关闭:它不完全是UTF-16,而是像UCS-2;但无论哪种方式,它确实对大多数字符使用2个字节(和2个字符的序列,即一些很少使用的代码点的4个字节)。
ObjectOutputStream使用称为修改的UTF-8的东西,它类似于UTF-8,但零字符表示为2字节序列,根据UTF-8不合法(由于编码的唯一性限制),但是那种自然地解码回值0。
但你真正要问的是“它是否有效以便我写一个字符串,读取一个字符串” - 答案是肯定的。 JDK在写入字节时执行正确的编码,在读取时进行解码。
对于它的价值,你最好为字符串使用“writeUTF()”方法,因为我认为结果输出更紧凑。但“writeObject()”也有效,只需要更多的元数据。
答案 2 :(得分:0)
为了补充一点,ObjectOutputStream.writeString()
将确定给定字符串的UTF长度,并以“标准”UTF或“长”UTF格式写入,其中“long”如javadoc中所述
“长”UTF格式与之相同 标准UTF,但它使用8 字节标题(而不是标准2 bytes)传达UTF编码 长度。
我是从代码中得到的......
private void writeString(String str, boolean unshared) throws IOException {
handles.assign(unshared ? null : str);
long utflen = bout.getUTFLength(str);
if (utflen <= 0xFFFF) {
bout.writeByte(TC_STRING);
bout.writeUTF(str, utflen);
} else {
bout.writeByte(TC_LONGSTRING);
bout.writeLongUTF(str, utflen);
}
}
并在writeObject(Object obj)
进行检查
if (obj instanceof String) {
writeString((String) obj, unshared);
}