ObjectOutputStream的writeObject方法使用什么字符编码?

时间:2010-12-08 17:35:05

标签: java character-encoding utf-16 fileoutputstream objectoutputstream

我读到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表示?

感谢。

3 个答案:

答案 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);
}