Java 将字符串写入套接字的输出流
我正在从事一个适应服务器-客户机体系结构的项目。在客户端和服务器之间传输的消息是字符串和字节数组的组合。我需要事先发送整个消息的大小 查找字节数组的字节大小很简单,但是字符串就不是这样了。显然,我可以将这些字符串转换为字节数组(考虑编码)。但是,这些字符串可能很长,我不想为它们的副本分配内存(例如getBytes()分配一个新数组) 我的问题是,执行以下操作的内存效率最高的方法是什么Java 将字符串写入套接字的输出流,java,string,sockets,outputstream,Java,String,Sockets,Outputstream,我正在从事一个适应服务器-客户机体系结构的项目。在客户端和服务器之间传输的消息是字符串和字节数组的组合。我需要事先发送整个消息的大小 查找字节数组的字节大小很简单,但是字符串就不是这样了。显然,我可以将这些字符串转换为字节数组(考虑编码)。但是,这些字符串可能很长,我不想为它们的副本分配内存(例如getBytes()分配一个新数组) 我的问题是,执行以下操作的内存效率最高的方法是什么 查找字符串的字节大小(使用UTF-8编码) 将该大小写入输出流 将字符串写入输出流 逐个字符迭代字符串。为每个位
逐个字符迭代字符串。为每个位置调用
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高-低代理等)。您始终可以在数据包中“断开”消息,因此您可以对消息的某一部分进行计算和内存分配,迭代到另一部分,然后再次执行该操作。尝试DataOutputStream。看看javadoc@andy我会事先知道我要写的字符串的大小吗?多长是“long”,您是否确实证明了复制所需的空间/时间是禁止的?使用
CharsetEncoder
(字节计数部分相当简单)很可能是可行的,但我认为在做更复杂的事情之前,值得尝试证明最简单的方法是不够的。@JonSkeet我以前从事过一个涉及VCF文件解析的项目(>1GB,DNA遗传学材料)我不得不做很多分析工作,我开始意识到垃圾收集器的操作有多马虎,所以从那时起我就对Java有点偏执了。@mostruash:这都是关于选择你的战斗。定义你的需求,实现尽可能最简单的代码,测试它,然后在需要时使用更复杂的代码。这就是为什么我一直在寻找f或者将字符串写入某个临时输入流并检查我写入了多少字节,然后将该临时流传递到套接字。如果所有这些都发生而不复制周围的内容…你就明白了。