如何使用CharSet(不转换为String)对CharSequence进行编码



我想使用指定的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编码设施?

您可以使用CharsetCharSequence编码为字节数组:

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));
}

最新更新