【问题标题】:Java serialization - how many bytes for a character?Java序列化 - 一个字符有多少字节?
【发布时间】:2014-10-25 12:54:47
【问题描述】:

我正在序列化 Java 中的字符串对象。现在我想知道字符串中每个序列化字符的大小。

标准英文字母(例如“a”或“G”)是否只需要 1 或 2 个字节,而逗号或感叹号等特殊符号需要 8 个字节?

但是序列化字符串中有多少字节需要数字符号(0 - 9)?

编辑:我按以下方式进行序列化:

socket = new Socket(host, port);
ObjectOutputStream outputStream = new ObjectOutputStream(new BufferedOutputStream(socket.getOutputStream()));
outputStream.writeObject(request);
outputStream.flush();

使用 ObjectInputStream 以类似的方式完成反序列化。

要序列化(请求)的对象包含一个字符串类型的字段,例如可以是“aaaa”或“aAaA”或“a0A3a5”等(即大小写字母和数字)。

【问题讨论】:

  • Java 中的 'char' 是 16 位无符号值。这是没有符号位的两个字节。您可以通过阅读文档找到这一点。
  • 这里是原始数据类型的链接:docs.oracle.com/javase/tutorial/java/nutsandbolts/…
  • 您说的是 UTF-8,它是一种可变长度的 unicode 编码。字符长度取决于您用于序列化数据的编码。因此,如果您告诉我们您如何序列化您的数据,我们可以回答。
  • @nomoa 我已经编辑了我的帖子,现在显示了序列化

标签: java serialization


【解决方案1】:

您使用 JAVA 序列化,因此它符合 http://docs.oracle.com/javase/6/docs/platform/serialization/spec/protocol.html

String 对象的表示由长度信息组成 后跟以修改后的 UTF-8 编码的字符串的内容。这 修改后的 UTF-8 编码与 JavaTM Virtual 中使用的相同 机器和 java.io.DataInput 和 DataOutput 接口;它 补充的表示与标准 UTF-8 不同 字符和空字符。长度的形式 信息取决于修改后的 UTF-8 中字符串的长度 编码。如果给定 String 修改后的 UTF-8 编码小于 长度超过 65536 字节,长度写为 2 字节 表示一个无符号的 16 位整数。从 JavaTM 2 开始 平台,标准版,v1.3,如果字符串的长度在 修改UTF-8编码为65536字节以上,长度写入 以 8 个字节表示一个有符号的 64 位整数。类型代码 在序列化流中的 String 之前指示哪个 格式用于写入字符串。

字符串被序列化为 UTF-8,因此 ASCII 字符用 1 个字节编码,而数字是 ASCII 是的,它们用 1 个字节编码。

更多信息请参见http://en.wikipedia.org/wiki/UTF-8

【讨论】:

  • 当然这仅适用于请求对象背后的类型依赖于默认序列化而不是其字段的自定义序列化过程。
  • 有没有可能在 outputStream.writeObject(request); 中看到对象的序列化了多少字节?是?
  • 不是开箱即用,但您可以在 OutputStream 之上实现一个包装类,该类将计算写入的每个字节。或者,如果只是为了查看/测试实验,您可以将数据写入 ByteArrayOuputStream,然后计算生成的 byte[] 长度。
  • 对于包装器,请查看此处的示例:github.com/dougm/jets3t/blob/master/src/org/jets3t/service/io/…。而对于 ByteArrayOuputStream 只需写入它而不是您的 Socket 并计算 ByteArrayOuputStream.toByteArray().length
【解决方案2】:

ObjectOutputStream 旨在写入对象。一个字符大约需要 78 个字节。如果你想把一个字符写成两个字节,你可以使用 DataOutputStream writeChar 或者如果你想使用一个字节,你可以 write(ch);

【讨论】:

  • 我想写对象,但对象包含一个字符串(在其他字段中)。因此,我在问字符串中的一个字符在对象的序列化输出中将占用多少字节。真的是78字节吗?因此,如果我正在序列化一个包含 100 个字符的字符串的对象,这已经是 100*78 字节......
  • 当您使用对象流时,第一个字符将使用大约 78 个字节,但是基于 UTF-8 编码,每个附加字符将使用 1-3 个字节。如果您使用通用对象编码器,那是因为您并不特别关心它是如何编码的。如果你想对你正在编码的内容做出假设,从而控制使用多少字节,你必须自己做更多的工作。
  • 好的。如何测量调用 writeObject 或 readObject 写入或接收的字节数?
  • @user1684118 将ObjectObjectStream 写入ByteArrayOutputStream,完成后调用toByteArray().length
猜你喜欢
  • 1970-01-01
  • 2012-03-12
  • 2011-08-30
  • 1970-01-01
  • 2014-12-16
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2010-11-13
相关资源
最近更新 更多