我正在开发一个适应服务器-客户端架构的项目。在客户端和服务器之间传输的消息是字符串和字节数组的组合。我需要事先发送整个消息的大小。
查找字节数组的字节大小是微不足道的,但对于字符串则不然。显然,我可以将这些字符串转换为字节数组(考虑到编码)。但是,这些字符串可能很长,我不想为它们的副本分配内存(例如 getBytes() 分配一个新数组)。
我的问题是,执行以下操作的最节省内存的方法是什么?
- 查找字符串的字节大小(使用 UTF-8 编码)
- 将该大小写入输出流
- 将字符串写入输出流
我正在开发一个适应服务器-客户端架构的项目。在客户端和服务器之间传输的消息是字符串和字节数组的组合。我需要事先发送整个消息的大小。
查找字节数组的字节大小是微不足道的,但对于字符串则不然。显然,我可以将这些字符串转换为字节数组(考虑到编码)。但是,这些字符串可能很长,我不想为它们的副本分配内存(例如 getBytes() 分配一个新数组)。
我的问题是,执行以下操作的最节省内存的方法是什么?
逐个字符地迭代字符串。调用codePointAt()
每个位置以获取其 unicode 代码点。根据代码点,您可以推断以 UTF-8 编码时需要多少字节:
Codepoint range | UTF-8 bytes
-----------------------------
0 - 127 | 1
128 - 2047 | 2
2048 - 65535 | 3
65536 + | 4
但在你这样做之前,你应该首先验证这是否真的有必要。无论如何,传递给套接字的字符串很可能在内部被复制到字节数组中。
如果大小不是关键问题,请对字符串使用 UTF16-BE 编码。在这种情况下,大小将是字符串长度 * 2。
在这种模式下,您可以一个一个地写入 Java 字符,而无需进行额外的处理(Unicode 高低代理等)。
您总是可以在数据包中“分解”您的消息,因此您可以对消息的某些部分进行计算和内存分配,迭代到另一部分并再次执行此操作。