当前位置: 首页 > 知识库问答 >
问题:

Java中ByteBuffer和字符串之间转换的问题

张可人
2023-03-14

我目前正在开发一个应用程序,用户可以通过十六进制编辑器界面编辑ByteBuffer,也可以通过JTextPane编辑相应的文本。我当前的问题是因为JTextPane需要一个字符串,我需要在显示值之前将ByteBuffer转换为字符串。但是,在转换过程中,无效字符将替换为字符集默认替换字符。这会压缩无效值,因此当我将其转换回字节缓冲区时,无效字符值将替换为默认替换字符的字节值。有没有一种简单的方法可以在字符串中保留无效字符的字节值?我读过下面的stackoverflow文章,但通常人们只想替换不可打印的字符,我需要保留它们。

JavaByteBuffer到字符串

Java:将字符串与ByteBuffer进行转换以及相关问题

有没有一种简单的方法可以做到这一点,或者我需要跟踪文本编辑器中发生的所有更改,并将它们应用到ByteBuffer?

下面是演示问题的代码。代码使用byte[]而不是ByteBuffer,但问题是相同的。

        byte[] temp = new byte[16];
        // 0x99 isn't a valid UTF-8 Character
        Arrays.fill(temp,(byte)0x99);

        System.out.println(Arrays.toString(temp));
        // Prints [-103, -103, -103, -103, -103, -103, -103, -103, -103, -103, -103, -103, -103, -103, -103, -103]
        // -103 == 0x99

        System.out.println(new String(temp));
        // Prints ����������������
        // � is the default char replacement string

        // This takes the byte[], converts it to a string, converts it back to a byte[]
        System.out.println(Arrays.toString(new String(temp).getBytes()));
        // I need this to print [-103, -103, -103, -103, -103, -103, -103, -103, -103, -103, -103, -103, -103, -103, -103, -103]
        // However, it prints
        //[-17, -65, -67, -17, -65, -67, -17, -65, -67, -17, -65, -67, -17, -65, -67, -17, -65, -67, -17, -65, -67, -17, -65, -67, -17, -65, -67, -17, -65, -67, -17, -65, -67, -17, -65, -67, -17, -65, -67, -17, -65, -67, -17, -65, -67, -17, -65, -67]
        // The printed byte is the byte representation of �

共有2个答案

宰宣
2023-03-14
匿名用户

你认为新字符串(temp)是什么。getBytes()可以吗?

我可以告诉你它做了一些不好的事情。

  1. 它使用默认编码将temp转换为String,这可能是错误的,并且可能会丢失信息

要将字节[]转换为字符串,必须始终将字符集传递到字符串构造函数中,或者直接使用解码器。因为您是从缓冲区工作的,所以您可能会发现解码器API与之相投。

要将String转换为byte[],您必须始终调用getBytes(Charset),以便您知道您使用的是正确的字符集。

根据评论,我现在怀疑你在这里的问题是,你需要编写代码,就像下面这样,将你的用户界面从字节转换为十六进制。(

String getHexString(byte[] bytes) {
    StringBuilder builder = new StringBuilder();
    for (byte b : bytes) {
       int nibble = b >> 4;
       builder.append('0' + nibble);
       nibble = b & 0xff;
       builder.append('0' + nibble);
    }
    return builder.toString();
}

华森
2023-03-14

尤其是UTF-8会出错

    byte[] bytes = {'a', (byte) 0xfd, 'b', (byte) 0xe5, 'c'};
    String s = new String(bytes, StandardCharsets.UTF_8);
    System.out.println("s: " + s);

一个人需要一个CharsetDecoder。在那里,可以忽略(=删除)或替换违规字节,或者默认情况下:让异常被抛出。

对于JTextPane,我们使用超文本标记语言,因此我们可以在中编写违规字节的十六进制代码。

    ByteBuffer byteBuffer = ByteBuffer.wrap(bytes);
    CharsetDecoder decoder = StandardCharsets.UTF_8.newDecoder();
    CharBuffer charBuffer = CharBuffer.allocate(bytes.length * 50);
    charBuffer.append("<html>");
    for (;;) {
        try {
            CoderResult result = decoder.decode(byteBuffer, charBuffer, false);
            if (!result.isError()) {
                break;
            }
        } catch (RuntimeException ex) {
        }
        int b = 0xFF & byteBuffer.get();
        charBuffer.append(String.format(
            "<span style='background-color:red; font-weight:bold'> %02X </span>",
            b));
        decoder.reset();
    }
    charBuffer.rewind();
    String t = charBuffer.toString();
    System.out.println("t: " + t);

代码并没有反映一个非常好的API,但是可以使用它。

 类似资料:
  • 问题内容: 这是将ByteBuffer转换为String的正确方法吗? 我问的原因是,这看起来太简单了,而其他方法,例如Java:在ByteBuffer和ByteBuffer之间来回转换字符串以及相关的问题看起来却更加复杂。 问题答案: 编辑(2018): @xinyongCheng编辑的同级答案是一种更简单的方法,应该被接受。 如果您知道字节在平台的默认字符集中,则您的方法将是合理的。在您的示例

  • 我们正试图在iReport中使用Cassandra插件。插件等被正确地嵌入到iReport中。写入的CQL只获取3列,列名也出现在读取字段中。

  • 问题内容: 您不能从int转换为char,因此这是非法的 , 但是,这是允许的。 这不是纯数字和文字吗?如何允许? 问题答案: 实际上是Java中的无符号16位整数类型。 与其他整数类型一样,您可以执行从整数常量到任何整数类型的赋值转换,只要它在适当的范围内即可。这就是为什么 也可以。 从JLS,第5.2节: 此外,如果该表达式是类型为byte,short,char或int的常量表达式(第15.2

  • 问题内容: 是否存在一种普遍接受的技术,可以有效地将JavaScript字符串转换为ArrayBuffers,反之亦然?具体来说,我希望能够将ArrayBuffer的内容写入并读回。 问题答案: 更新 -五年来,规范中现在有了新方法(请参阅下面的支持),可以使用正确的编码在字符串和类型数组之间进行转换。 TextEncoder 该代表: 该接口表示用于特定方法的编码器,即特定的字符编码,例如, ,

  • 问题内容: 有谁知道如何将a转换为Base64字符串,然后将其反转? 我有以下代码;编码之前的原始图像是好的,但是编码和解码后我只能得到空白图像。 问题答案: 迅速 首先我们需要有图像的NSData Swift 2.0 >编码 Swift 2.0 >解码 Swift 3.0 >解码 编码方式 : 解码 : 斯威夫特3.0 目标C iOS7>版本 您可以使用 编码方式 : 解码 : iOS 6.1和

  • 问题内容: 我正在使用Java NIO进行套接字连接,并且我的协议是基于文本的,因此我需要能够将字符串转换为ByteBuffer,然后再将其写入SocketChannel,并将传入的ByteBuffer转换回String。目前,我正在使用以下代码: 这在大多数情况下都有效,但是我怀疑这是进行此转换各个方向的首选(或最简单)方法,还是有其他尝试的方法。偶尔,和看似随意,将呼叫和将抛出一个 异常,或类