java 快速 ByteBuffer 到 CharBuffer 或 char[]

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/5936275/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-30 13:32:32  来源:igfitidea点击:

Fast ByteBuffer to CharBuffer or char[]

javabytearrayniobytebufferarrays

提问by towi

What is the fastest method to convert a java.nio.ByteBuffer ainto a (newly created) CharBuffer bor char[] b.

将 ajava.nio.ByteBuffer a转换为(新创建的)CharBuffer bchar[] b.

By doing this it is important, that a[i] == b[i]. This means, that not a[i]and a[i+1]together make up a value b[j], what getChar(i)would do, but the values should be "spread".

这样做很重要,即a[i] == b[i]. 这意味着,不a[i]a[i+1]一起组成一个值b[j]getChar(i)会做什么,但这些值应该是“传播”的。

byte a[] = { 1,2,3, 125,126,127, -128,-127,-126 } // each a byte (which are signed)
char b[] = { 1,2,3, 125,126,127,  128, 129, 130 } // each a char (which are unsigned)

Note that byte:-128has the same (lower 8) bits as char:128. Therefore I assume the "best" interpretation would be as I noted it above, because the bits are the same.

请注意, 与byte:-128具有相同的(低 8)位char:128。因此,我假设“最佳”解释将是我上面提到的,因为位是相同的。

After that I also need the vice versatranslation: The most efficient way to get a char[]or java.nio.CharBufferback into a java.nio.ByteBuffer.

之后,我还需要反之亦然的翻译:将 achar[]java.nio.CharBuffer返回到java.nio.ByteBuffer.

回答by Pa?lo Ebermann

So, what you want is to convert using the encoding ISO-8859-1.

所以,您想要的是使用编码 ISO-8859-1 进行转换。

I don't claim anything about efficiency, but at least it is quite short to write:

我对效率没有任何要求,但至少写起来很短:

CharBuffer result = Charset.forName("ISO-8859-1").decode(byteBuffer);

The other direction would be:

另一个方向是:

ByteBuffer result = Charset.forName("ISO-8859-1").encode(charBuffer);

Please measure this against other solutions. (To be fair, the Charset.forNamepart should not be included, and should also be done only once, not for each buffer again.)

请对照其他解决方案衡量这一点。(公平地说,Charset.forName不应包括该部分,也应仅执行一次,而不是对每个缓冲区再次执行。)

From Java 7 on there also is the StandardCharsetsclass with pre-instantiated Charset instances, so you can use

从 Java 7 开始,还有带有预实例化 Charset 实例的StandardCharsets类,因此您可以使用

CharBuffer result = StandardCharsets.ISO_8859_1.decode(byteBuffer);

and

ByteBuffer result = StandardCharsets.ISO_8859_1.encode(charBuffer);

instead. (These lines do the same as the ones before, just the lookup is easier and there is no risk to mistype the names, and no need to catch the impossible exceptions.)

反而。(这些行与之前的行一样,只是查找更容易,并且没有错误输入名称的风险,并且不需要捕获不可能的异常。)

回答by Peter Lawrey

I would agree with @Ishtar's, suggest to avoid converting to a new structure at all and only convert as you need it.

我同意@Ishtar 的观点,建议完全避免转换为新结构,仅在需要时进行转换。

However if you have a heap ByteBuffer you can do.

但是,如果您有一个堆 ByteBuffer,您就可以做到。

ByteBuffer bb = ...
byte[] array = bb.array();
char[] chars = new char[bb.remaining()];
for (int i = 0; i < chars.length; i++)
    chars[i] = (char) (array[i + bb.position()] & 0xFF);

回答by StaxMan

Aside from deferring creation of CharBuffer, you may be able to get by without one. If code that is using data as characters does not strictly need a CharBuffer or char[], just do simple on-the-fly conversion; use ByteBuffer.get() (relative or absolute), convert to char (note: as pointed out, you MUST unfortunately explicitly mask things; otherwise values 128-255 will be sign-extended to incorrect values, 0xFF80 - 0xFFFF; not needed for 7-bit ASCII), and use that.

除了推迟 CharBuffer 的创建之外,你也许可以不用它。如果使用数据作为字符的代码并不严格需要 CharBuffer 或 char[],只需进行简单的动态转换即可;使用 ByteBuffer.get()(相对或绝对),转换为字符(注意:正如所指出的,不幸的是,你必须明确地屏蔽事物;否则值 128-255 将被符号扩展为不正确的值,0xFF80 - 0xFFFF;不需要7 位 ASCII),并使用它。