Java 快速字节缓冲到CharBuffer或char[]

Java 快速字节缓冲到CharBuffer或char[],java,bytearray,nio,bytebuffer,arrays,Java,Bytearray,Nio,Bytebuffer,Arrays,将java.nio.ByteBuffer a转换为(新创建的)CharBuffer b或char[]b的最快方法是什么 这样做很重要,a[i]==b[i]。这意味着,不是a[i]和a[i+1]一起构成一个值b[j],getChar(i)会做什么,但这些值应该是“分散的” 请注意,byte:-128与char:128具有相同的(低8)位。因此,我假设“最佳”解释将如我上面所述,因为位是相同的 之后,我还需要反之亦然翻译:将char[]或java.nio.CharBuffer重新转换为java.ni

java.nio.ByteBuffer a
转换为(新创建的)
CharBuffer b
char[]b
的最快方法是什么

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

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


之后,我还需要反之亦然翻译:将
char[]
java.nio.CharBuffer
重新转换为
java.nio.ByteBuffer

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

但是,如果您有一堆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);
ByteBuffer bb=。。。
字节[]数组=bb.array();
char[]chars=新字符[bb.remaining()];
for(int i=0;i
因此,您需要的是使用编码ISO-8859-1进行转换

我不主张任何关于效率的东西,但至少它写得很短:

CharBuffer result = Charset.forName("ISO-8859-1").decode(byteBuffer);
另一个方向是:

ByteBuffer result = Charset.forName("ISO-8859-1").encode(charBuffer);
请对照其他解决方案来衡量这一点。(公平地说,
Charset.forName
部分不应该包括在内,而且应该只执行一次,而不是针对每个缓冲区执行一次。)

从Java7开始,还有一个带有预实例化字符集实例的类,因此您可以使用

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


相反。(这些行的功能与前面的行相同,只是查找更容易,不会出现键入错误的风险,也不需要捕获不可能的异常。)

除了推迟创建CharBuffer之外,您可能不需要一个。
如果使用数据作为字符的代码不需要CharBuffer或char[],只需进行简单的动态转换;使用ByteBuffer.get()(相对或绝对),将其转换为字符(注意:如前所述,您必须不幸地显式屏蔽内容;否则,值128-255将被符号扩展为不正确的值,0xFF80-0xFFFF;7位ASCII不需要),然后使用它。

您希望如何处理此字符缓冲区?如果输入一个2字节字符,会发生什么?翻译后的字节数组应该是什么样子?根据您的需要,最有效的方法可能是根本不转换。换句话说,您希望将
ByteBuffer
的内容解释为使用ISO-8859-1编码的字符序列?假设
char[]
缓冲区中没有大于
0xff
的值用于反向翻译。任何行为/崩溃都可以(“未指定”)。ISO-8859-1?据我所知,有些字节不能被任何代码页翻译(例如
\0
)?我认为,如果您将一个8位的数据流转储到内存中,那么许多代码页转换库都不会很好地接受它。但是我不懂Java,我会查一下。假设我有图片/图像数据,嗯?如果您有图片/图像数据,那么为什么您关心字符?也许如果你描述了你想要完成的事情,而不是你想要的实现方法,你会得到更相关的答案。@towi-那么你想要的数据类型叫做
short
Ok,这是通用的,也是安全的。谢谢但我希望可能会有一个API调用来实现这一点?你可以确定编码的工作方式是你想要的。您可以尝试“US-ASCII”,但我不知道它适用于所有0-255。不,US-ASCII仅适用于0-127,其他字节被映射(在Java中,当不使用字符集API进行更精细的控制时)到
?”
,其他字符映射到
(字节)?
。使用ISO-8859-1可完全覆盖8位范围,即执行循环所做的操作。java.nio.StandardCharsets.ISO_8859_1及其同级提供对字符集的简单引用,而无需字符串查找或引发异常。
CharBuffer result = StandardCharsets.ISO_8859_1.decode(byteBuffer);
ByteBuffer result = StandardCharsets.ISO_8859_1.encode(charBuffer);