2013-05-01 100 views
3

我正在开发一个适应服务器 - 客户端体系结构的项目。在客户端和服务器之间传输的消息是字符串和字节数组的组合。我需要事先发送整个消息的大小。将字符串写入套接字的输出流

查找字节数组的字节大小很简单,但字符串并非如此。很明显,我可以将这些字符串转换为字节数组(考虑编码)。但是,这些字符串可能很长,我不想为它们的副本分配内存(例如getBytes()分配一个新数组)。

我的问题是,进行以下操作的内存效率最高的方法是什么?字符串的

  1. 查找字节大小(使用UTF-8编码)
  2. 编写大小到输出流
  3. 写入字符串输出流
+0

尝试DataOutputStream。看看javadoc – andy 2013-05-01 14:56:47

+0

@andy我会知道我将要写入的字符串的大小吗? – mostruash 2013-05-01 15:00:35

+0

“多久”多久了,您是否真的证明了复制所需的空间/时间是过分的?使用CharsetEncoder来完成此操作可能是可行的(字节计数部分相当简单),但我认为在做更复杂的事情之前,尽量证明最简单的方法是不够的。 – 2013-05-01 15:03:42

回答

1

迭代由字符串字符字符。请拨打codePointAt()获取每个位置的Unicode码点。根据不同的代码点,你可以推断出多少字节UTF-8编码时,将需要:

Codepoint range | UTF-8 bytes 
----------------------------- 
0  - 127  | 1 
128 - 2047 | 2 
2048 - 65535 | 3 
65536 +   | 4 

但你这样做之前,你应该先验证这是否是真的有必要。无论如何,传递给套接字的字符串很可能在内部复制到字节数组中。

+0

这就是为什么我一直在寻找一种方法将字符串写入一些临时输入流,并检查我写了多少字节,并将该临时流传递给套接字。如果所有这些都会发生而没有复制东西......你明白了。 – mostruash 2013-05-01 15:18:41

1

如果大小不是关键问题,请对字符串使用UTF16-BE编码。在这种情况下,大小将为字符串长度* 2.

在此模式下,您可以逐个编写Java字符,而无需执行额外的处理(Unicode高低代理等)。

+0

+1年后,你的回答很有用。 – mostruash 2014-09-11 06:52:50

0

您可以随时在信息包中“分解”您的信息,因此您可以为信息的某些部分进行计算和内存分配,迭代到另一部分并再次执行。