Java中的字符是1字节还是2字节?

时间:2011-05-13 06:44:59

标签: java string unicode ascii character

我认为java中的字符是java doc中建议的16位字符。字符串不是这样吗?我有一个代码将对象存储到文件中:

public static void storeNormalObj(File outFile, Object obj) {
    FileOutputStream fos = null;
    ObjectOutputStream oos = null;
    try {
        fos = new FileOutputStream(outFile);
        oos = new ObjectOutputStream(fos);
        oos.writeObject(obj);
        oos.flush();
    } catch (IOException e) {
        e.printStackTrace();
    } finally {
        try {
            oos.close();
            try {
                fos.close();
            } catch (Exception e) {
                e.printStackTrace();
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

基本上,我尝试将字符串"abcd"存储到文件"output"中,当我用编辑器打开output并删除无字符串部分时,剩下的只是字符串“abcd”,总共4个字节。谁知道为什么?对于ASCII支持的字符串,java是否使用ASCII而不是UNICODE自动节省空间?感谢

5 个答案:

答案 0 :(得分:7)

(我认为“无字符串部分”是指ObjectOutputStream在创建时发出的字节。您可能不想使用ObjectOutputStream,但我不知道您的要求。)

仅供参考,Unicode和UTF-8不是一回事。 Unicode是一种标准,除其他外,指定可用的字符。 UTF-8是一种字符编码,用于指定这些字符在1和0中的物理编码方式。 UTF-8可以使用1个字节表示ASCII(< = 127),最多4个字节表示其他Unicode字符。

UTF-8是ASCII的严格超集。因此,即使您为文件指定UTF-8编码并向其写入“abcd”,它也只包含这四个字节:它们在ASCII中具有与UTF-8中相同的物理编码。

您的方法使用的ObjectOutputStream实际上具有与ASCII或UTF-8截然不同的编码!如果您仔细阅读Javadoc,如果obj是一个字符串并且已经在流中发生,则对writeObject的后续调用将导致对前一个字符串的引用被发出,可能导致更少的字节到写在重复字符串的情况下。

如果您认真理解这一点,那么您真的应该花大量时间阅读有关Unicode和字符编码系统的知识。维基百科有一篇关于Unicode的优秀文章作为开始。

答案 1 :(得分:2)

是的,char在Java运行时环境的上下文中只是Unicode。如果您希望使用16位编码进行编写,请使用FileWriter

    FileWriter outputStream = null;

    try {
        outputStream = new FileWriter("myfilename.dat");

        int c;
        while ((c = inputStream.read()) != -1) {
            outputStream.write(c);
        }
    } finally {
        if (outputStream != null) {
            outputStream.close();
        }
    }

答案 2 :(得分:1)

如果你看一下String的来源,它会注意到它调用DataOutput.writeUTF来编写字符串。如果你读到它,你会发现它们被写成“修改过的UTF-8”。细节很冗长,但如果你不使用非7位ascii,是的,它需要一个字节。如果你想要gory细节,请查看DataOutput.writeUTF()中的EXTREMELY long javadoc

答案 3 :(得分:0)

您可能有兴趣知道Java Update 21性能版本及更高版本中有-XX:+UseCompressedStrings选项。这将允许String对不需要byte[]

的字符串使用char[]

尽管Java Hotspot VM Options指南建议默认情况下可以启用,但这可能只适用于性能发布。如果我明确地打开它,它似乎对我有用。

答案 4 :(得分:-1)

那么你期望一个16*4=64 bits = 8 bytes文件吗?超过UTF-8或ASCII编码。将文件写入文件后。内存(就空间而言)管理取决于操作系统。并且您的代码无法控制它。