从 ByteBuffer 读取以 NUL 结尾的字符串

jiw*_*ene 3 java nio bytebuffer text-decoding

如何从 JavaByteBuffer中读取以 NUL 结尾的 UTF-8 字符串ByteBuffer#position()

\n
ByteBuffer b = /* 61 62 63 64 00 31 32 34 00 (hex) */;\nString s0 = /* read first string */;\nString s1 = /* read second string */;\n\n// `s0` will now contain \xe2\x80\x9cABCD\xe2\x80\x9d and `s1` will contain \xe2\x80\x9c124\xe2\x80\x9d.\n
Run Code Online (Sandbox Code Playgroud)\n

我已经尝试过使用Charsets.UTF_8.decode(b),但似乎这个函数忽略当前ByteBuffer位置并读取直到缓冲区末尾。

\n

有没有更惯用的方法从字节缓冲区读取此类字符串,而不是寻找包含 0 的字节并将缓冲区限制为它(或将带有字符串的部分复制到单独的缓冲区中)?

\n

dre*_*our 6

我不知道惯用语的意思是“一个衬垫”(这并不奇怪,因为以 NUL 结尾的字符串不是 Java 规范的一部分)。

我想到的第一件事是b.slice().limit(x)仅在所需字节上创建一个轻量级视图(比将它们复制到任何地方更好,因为您可以直接使用缓冲区)

ByteBuffer b = ByteBuffer.wrap(new byte[] {0x61, 0x62, 0x63, 0x64, 0x00, 0x31, 0x32, 0x34, 0x00 });
int i;
while (b.hasRemaining()) {
  ByteBuffer nextString = b.slice(); // View on b with same start position
  for (i = 0; b.hasRemaining() && b.get() != 0x00; i++) {
    // Count to next NUL
  }
  nextString.limit(i); // view now stops before NUL
  CharBuffer s = StandardCharsets.UTF_8.decode(nextString);
  System.out.println(s);
}
Run Code Online (Sandbox Code Playgroud)