我想使用指定的CharSet将CharSequence写入OutputStream。基本上,当调用write(String)时,用相同的CharSet初始化的Writer会做什么。
问题是,要编写许多CharSequence,其中一些相当大。更复杂的是,所有内容都可能被写入多个OutputStream。我可以通过使用(实际上我目前已经用这种方式实现了)来轻松地实现它:
byte[] rawBytes = CharSequence.toString().getBytes(CharSet)
for (OutputStream out : outputTargets) {
out.write(rawBytes);
}
但很明显,String是一个完全不需要的垃圾对象,byte[]数组也是如此。我正在寻找一种方法,允许我在没有中间对象的情况下直接进行编码。令人惊讶的是,这似乎是不可能的——无论我在JRE中看到哪里,只要接受了CharSequence,它就会在完成任何工作之前快速转换为String。
CharSet的大部分(全部?)转换工作似乎是在非公共类中完成的,所以我还没有找到任何方法以透明和合法的方式访问这些工作。
如何避免垃圾/直接使用JRE的CharSet编码设施?
您可以使用Charset
将CharSequence
编码为字节数组:
private static byte[] encodeUtf8(CharSequence cs) {
ByteBuffer bb = Charset.forName("UTF-8").encode(CharBuffer.wrap(cs));
byte[] result = new byte[bb.remaining()];
bb.get(result);
return result;
}
如果您使用的不是OutputStream
,而是WritableByteChannel
的实例,那么它的write
方法直接采用ByteBuffer
,因此您甚至不需要先将字节缓冲区复制到字节数组。
遍历序列中的字符并将它们写入编写器。
OutputStream outputStream = ....
CharSequence charSequence = ....
Charset charset = ....
Writer writer = new OutputStreamWriter(outputStream, charset);
for (int i = 0; i < charSequence.length(); i++) {
writer.write(charSequence.charAt(i));
}