我有一个非常有趣的话题 - 至少对我而言。给定带有字节的ByteArrayOutputStream,例如UTF-8,我需要一个可以"翻译"那些字节到另一个 - 新 - ByteArrayOutputStream例如UTF-16,或ASCII或你命名它。我天真的方法是使用一个InputStreamReader并提供所需的编码,但这不起作用,因为它会读入char []并且我只能将byte []写入新的BAOS。
public byte[] convertStream(Charset encoding) {
ByteArrayInputStream original = new ByteArrayInputStream(raw.toByteArray());
InputStreamReader contentReader = new InputStreamReader(original, encoding);
ByteArrayOutputStream converted = new ByteArrayOutputStream();
int readCount;
char[] buffer = new char[4096];
while ((readCount = contentReader.read(buffer, 0, buffer.length)) != -1)
converted.write(buffer, 0, readCount);
return converted.toByteArray();
}
现在,这显然不起作用,我正在寻找一种方法来使这种情况成为可能,而无需在字节[]之外构建一个字符串。
@Edit: 因为看起来很难看清楚的事情。 1)raw:ByteArrayOutputStream,包含从客户端发送给我们的BINARY对象的字节。字节通常以UTF-8作为HTTP消息的一部分。 2)此处的目标是将此BINARY数据发送到内部系统,该系统不灵活 - 这是一个内部系统 - 它接受UTF-16中的此类附件。我不知道为什么不问,它也是这样。
因此,为了证明我的问题:有没有办法将字节数组从Charset A转换为Charset B或编码你的选择。再一次构建字符串不是我追求的目标。
谢谢你,并希望清除可疑的部分:)。
答案 0 :(得分:8)
如评论中所述,我只是转换为字符串:
String text = new String(raw.toByteArray(), encoding);
byte[] utf8 = text.getBytes(StandardCharsets.UTF_8);
然而,如果这不可行(出于某些未说明的原因......)你现在所拥有的几乎就是 - 你只需要在混合中添加OutputStreamWriter
:
// Nothing here should throw IOException in reality - work out what you want to do.
public byte[] convertStream(Charset encoding) throws IOException {
ByteArrayInputStream original = new ByteArrayInputStream(raw.toByteArray());
InputStreamReader contentReader = new InputStreamReader(original, encoding);
int readCount;
char[] buffer = new char[4096];
try (ByteArrayOutputStream converted = new ByteArrayOutputStream()) {
try (Writer writer = new OutputStreamWriter(converted, StandardCharsets.UTF_8)) {
while ((readCount = contentReader.read(buffer, 0, buffer.length)) != -1) {
writer.write(buffer, 0, readCount);
}
}
return converted.toByteArray();
}
}
请注意,您仍然在内存中创建额外的临时数据副本,无论是UTF-8而不是UTF-16 ......但从根本上说,这几乎不比创建字符串更有效。
如果内存效率是一个特别关注的问题,那么你可以执行多次传递以计算出需要多少字节,创建一个写长度的字节数组,然后将代码调整为直接写入该字节数组。